Embed surveys into any web page with a single script tag. The SDK renders your survey as a popup, slide-in, or inline widget, no framework required.
Set window.RevuloopConfig with your survey ID and options, then load the SDK script. The SDK reads the config and mounts the widget automatically.
<script>
window.RevuloopConfig = {
surveyId: "YOUR_SURVEY_ID",
type: "slider", // "popup" | "slider" | "inline"
position: "bottom-right",
buttonText: "Take Survey",
buttonColor: "#0D9488",
};
</script>
<script src="https://app.revuloop.com/revuloop-embed.js"></script>You can find your survey ID in the dashboard under Survey → Distribute → Embed, which also generates a ready-to-paste snippet.
A launcher button opens the survey in a centered modal overlay.
A launcher button slides the survey in from a corner of the screen.
The survey renders directly inside a container element on your page.
For inline mode, add a container element and point containerId at it:
<div id="revuloop-survey"></div>
<script>
window.RevuloopConfig = {
surveyId: "YOUR_SURVEY_ID",
type: "inline",
containerId: "revuloop-survey",
};
</script>
<script src="https://app.revuloop.com/revuloop-embed.js"></script>The script also exposes a global window.Revuloop object so you can create and control widgets from your own code, useful in single-page apps:
// Each method takes (surveyId, options)
Revuloop.createSlider("YOUR_SURVEY_ID", {
position: "bottom-right",
buttonText: "Feedback",
buttonColor: "#0D9488",
onComplete: (data) => console.log("Completed:", data),
onClose: () => console.log("Closed"),
});
Revuloop.createPopup("YOUR_SURVEY_ID", { buttonText: "Take Survey" });
// Inline takes the container element ID as its second argument
Revuloop.createInline("YOUR_SURVEY_ID", "revuloop-survey");
// Teardown (e.g. on route change)
Revuloop.destroyAll();| Option | Type | Description |
|---|---|---|
| surveyId | string | Required. The ID of the survey to display. |
| type | "popup" | "slider" | "inline" | Display mode. Defaults to “slider”. |
| position | "bottom-right" | "bottom-left" | "top-right" | "top-left" | Launcher / panel position for popup and slider. Defaults to “bottom-right”. |
| buttonText | string | Launcher button label (popup & slider). |
| buttonColor | string | Launcher button color (hex). Defaults to #0D9488. |
| containerId | string | Target element ID for inline mode. Required when type is “inline”. |
| autoShow | boolean | Open the survey automatically after autoShowDelay. Defaults to false (opens on button click). |
| autoShowDelay | number (ms) | Delay before auto-opening when autoShow is true. Defaults to 3000. |
| showOnce | boolean | When auto-showing, only show once per browser session. Defaults to true. |
| autoStart | boolean | Skip the survey welcome screen and open on the first question. Defaults to true; set false to show the welcome screen. |
| onComplete | (data) => void | Called when the survey is completed. |
| onClose | () => void | Called when the widget is closed. |
| onLoad | () => void | Called when the survey has loaded. |
| onError | (error) => void | Called on a load or runtime error. |
The script-tag embed needs no token. The survey ID alone is enough to embed a launched, publicly accessible survey on any site. If you want to restrict which domains can load a survey, mint a short-lived embed token with your API key and pass it to the SDK:
POST /api/v1/embed/token
Authorization: Bearer rlk_live_...
{
"surveyId": "YOUR_SURVEY_ID",
"allowedDomains": ["app.example.com"],
"accessTokenExpiresInMinutes": 60,
"refreshTokenExpiresInDays": 30
}
// Response
{
"accessToken": "rlet_...", // short-lived embed token
"refreshToken": "rlrt_...", // used to mint new access tokens
"accessTokenExpiresAt": "2025-01-01T12:00:00Z",
"refreshTokenExpiresAt": "2025-01-31T12:00:00Z",
"surveyId": "YOUR_SURVEY_ID",
"allowedDomains": ["app.example.com"]
}Embedding requires a Pro or Business plan. Surveys owned by Free or Starter accounts cannot be embedded, and embed tokens can only be minted on those paid plans.
For bundled applications, the hosted script is also published to npm as @revuloop/embed : the same SDK bundle, so everything above works identically. It additionally exposes initWithToken for token-based, domain-restricted embedding.
npm install @revuloop/embed