This widget lets you inlcude the Indie Polls feature requests in any website. Indie Polls.
Add this script tag anywhere in your page (usually before </body>):
<script
src="https://indiepolls.io/widget/widget.js"
defer
data-public-token="YOUR_PUBLIC_TOKEN"
data-class-name="dark"
></script>
data-public-token: required. The public token of the poll/widget, generated from the Indie Polls backoffice. data-class-name: optional. Set to dark for dark mode, or leave empty for light. The script tag also supports a few optional attributes:
data-external-id: a stable identifier for the end user in your system. Used to prevent multiple submissions. data-email: pre-fill contributor email. data-name: pre-fill contributor name. data-embed-target: a CSS selector; if provided, the widget will be rendered inside the matching element instead of attaching to document.body. data-height: desired height for the widget container when using data-embed-target (e.g. 800px, 70vh, 100%). data-layout: set to inline to render the survey in the flow of the page where the snippet sits, without naming a container. Leave it off for the slide-in, modal and banner layouts, which are positioned against the viewport and stay attached to document.body. data-trigger-id: the id of an element on your page that opens the survey, in place of the floating launcher. See below. Example with more options:
<script
src="https://indiepolls.io/widget/widget.js"
defer
data-public-token="YOUR_PUBLIC_TOKEN"
data-external-id="user-123"
data-email="user@example.com"
data-name="Jane Doe"
data-class-name="dark"
data-embed-target="#indie-polls-widget-container"
data-height="800px"
></script>
Then in your HTML:
<div id="indie-polls-widget-container"></div>
Give the snippet a data-trigger-id and the floating launcher is not
shown: the survey opens, in its slide-in, modal or banner layout, when the
visitor clicks the element with that id. Use it when the survey should
start from something that looks like part of your site, such as a “Give
feedback” link in a menu.
<div id="give-feedback" role="button" tabindex="0">Give feedback</div>
<script
src="https://indiepolls.io/widget/widget.js"
defer
data-public-token="YOUR_PUBLIC_TOKEN"
data-trigger-id="give-feedback"
></script>
div, and clicks on
anything inside it count too. div made focusable with tabindex="0" also opens the survey on Enter
or Space. data-trigger-id. On the Max plan, the survey’s Widget tab can limit who the widget shows to. Below Max these settings are kept but not applied, and the widget shows to everyone.
data-attributes, such as plan is pro, signup_days greater than 30, role is not admin or company contains acme. Every rule has to
hold. Text is compared ignoring case; greater than and less than compare
numbers. The same attributes are stored with each answer, so results can
be broken down by them. <script
src="https://indiepolls.io/widget/widget.js"
defer
data-public-token="YOUR_PUBLIC_TOKEN"
data-attributes='{"plan":"pro","signup_days":42,"role":"member"}'
></script>
<script>
// Once the widget script has loaded, from anywhere in your page:
window.IndiePolls.track('checkout_completed');
</script>
IndiePolls.track(name) takes the event’s name, as typed in the Widget tab.
This is about showing the survey to the people it is meant for, not about
access: the rules run in the visitor’s browser, on what your page says.
On the Max plan, the survey’s Customizations tab takes a stylesheet of your
own. It applies to the hosted survey page and to the widget, where it stays
inside the widget’s shadow root and never reaches the rest of your page.
@import and a closing </style> tag are refused. The editor’s Insert
example button fills in the starter stylesheet below.
Style the ip- classes and the variables listed here. They are the same on
the hosted page and in the widget, and they stay the same between releases;
the other classes in the markup are utilities that can change at any time.
.ip-survey, on both surfaces. In the widget
that is the element inside the shadow root; :host does not work, since
the defaults are set on .ip-survey. .ip-survey, as in .ip-survey .ip-option,
so they win over the survey’s own styles in light and dark mode. .ip-option-selected and aria-pressed="true". --ip-primary-dark and
--ip-primary-contrast-dark when you set them, and the light ones when
you don’t. Inside .ip-survey, var(--ip-primary) and
var(--ip-primary-contrast) then give the colours for the current mode,
so your own rules that read them follow along. --ip-primary: Primary buttons, chosen answers and focus rings. Default: blue on the hosted page, amber in the widget. --ip-primary-contrast: Text on the primary colour. Default: white. --ip-primary-dark: The primary colour in dark mode. Default: the same as –ip-primary. --ip-primary-contrast-dark: Text on the primary colour in dark mode. Default: the same as –ip-primary-contrast. --ip-radius: Corners of answers, inputs and buttons. Default: 0.25rem. --ip-font: The survey’s font. Default: the default sans-serif. .ip-survey: The whole survey. Set the variables here. .ip-panel: The box the survey sits in: the card on the hosted page, the panel in the widget. .ip-header: The top of the survey, holding the title. .ip-logo: The logo in the widget’s header. Widget only. .ip-title: The survey’s title. .ip-intro: The intro screen, before the first question. .ip-progress: “Question 1 of 3”, above each question. .ip-question: The current question. .ip-question-prompt: The question’s text. .ip-option: An answer choice, including each point of a scale or rating. .ip-option-selected: A chosen answer, which also has aria-pressed set to true. .ip-scale: The row of points of a scale (NPS, CSAT, stars, Likert) or rating. .ip-input: A text, number, date or email box, and the name and email fields. .ip-button-primary: Start, Next and Submit. .ip-button-secondary: Back. .ip-outro: The thank-you screen after submitting. .ip-launcher: The floating button that opens the widget. Widget only. /* Starter stylesheet: keep what you need, delete the rest.
It works on the hosted survey page and in the embedded widget. */
/* Theme: the brand colour, corners and font, changed in one place. */
.ip-survey {
--ip-primary: #0f766e; /* buttons, chosen answers, focus */
--ip-primary-contrast: #ffffff; /* text on the primary colour */
--ip-primary-dark: #2dd4bf; /* the same two in dark mode */
--ip-primary-contrast-dark: #042f2e;
--ip-radius: 10px; /* answers, inputs and buttons */
--ip-font: Georgia, "Times New Roman", serif;
}
/* Parts: start each selector with .ip-survey so it wins over ours.
Inside the survey, var(--ip-primary) is the dark colour in dark mode. */
.ip-survey .ip-question-prompt {
font-size: 1.125rem;
}
.ip-survey .ip-option-selected {
font-weight: 600;
}
.ip-survey .ip-button-primary {
background-color: var(--ip-primary);
color: var(--ip-primary-contrast);
text-transform: uppercase;
letter-spacing: 0.04em;
}
test/index.html)You can also inject the widget dynamically and assign a random external id at runtime:
<script>
const dynamicUser = Math.random().toString(36).slice(2);
const s = document.createElement('script');
s.async = true;
s.src = 'https://indiepolls.io/widget/widget.js';
s.dataset.publicToken = 'YOUR_PUBLIC_TOKEN';
s.dataset.externalId = `user-${dynamicUser}`;
s.dataset.className = 'dark';
document.body.appendChild(s);
// Optionally, set s.dataset.embedTarget, s.dataset.height, etc.
</script>
--ip-primary-dark and --ip-primary-contrast-dark on .ip-survey and a dark widget uses them for its buttons, chosen answers, tints and focus rings, as the hosted survey page does. Each falls back to its light one, so a dark widget looks as before until they are set. .ip-progress class for custom CSS. When a branch skips ahead, the count skips with it. ip- classes and --ip-* theme variables for a Max survey’s own stylesheet, the same as on the hosted survey page. The stylesheet now also wins a tie with the widget’s own rules. data-trigger-id: open the survey from an element on your page instead of the floating launcher.