Introduction
This page explains how to show Expoints questionnaires on your website in a reliable and customer-friendly way. You can present a questionnaire as a pop-up, pop-in, or inline element.
Your Experience Manager provides the values you need to implement this page:
- Configuration ID (
configId) - Manual trigger key(s), when applicable
- Your instance URL (for example
https://yourcompany.expoints.nl)
If you do not have these details, contact service@expoints.nl.
Quick start
Add the loader snippet once, preferably before the closing </body> tag.
Replace <customer#> and configId with your own values.
<script type="text/javascript">
(function() {
var exp = document.createElement('script');
exp.type = 'text/javascript';
exp.async = true;
exp.onload = function() {
window.expoints = lightningjs.require('expoints', 'https://<customer#>.expoints.nl/m/Scripts/dist/expoints-external.min.js');
expoints('start', 'configId', { instanceUrl: 'https://<customer#>.expoints.nl' });
};
exp.src = 'https://<customer#>.expoints.nl/m/Scripts/dist/expoints-external-loader.min.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(exp, s);
})();
</script>
Start options
The start call accepts the following options object:
instanceUrl(required): your Expoints instance URL.debug(optional): writes detailed diagnostics to the browser console.logLevel(optional): custom log level whendebugis not enabled.
Debug during implementation
Enable debug mode while testing your integration:
expoints('start', 'configId', {
instanceUrl: 'https://<customer#>.expoints.nl',
debug: true
});
How questionnaires are triggered
You can launch questionnaires in two ways:
- Rule-based triggers configured in Expoints
- Manual triggers from your own JavaScript or tag manager (for example GTM)
Rule-based triggers in Expoints
In this model, Expoints decides whether to show a questionnaire based on rules configured by your Experience Manager. This is the easiest option when your timing and targeting can be fully managed in Expoints.
Common rule criteria include:
- Current URL (equals, contains, starts with)
- Previous URL
- Device type (desktop, tablet, mobile)
- Sampling chance (for example 1 in 10 visitors)
- Date and time conditions
Manual triggers
Use manual triggers when you want complete control over exactly when a questionnaire appears, such as after a conversion, form submission, or specific user action.
Use the manual trigger key provided by Expoints:
expoints.trigger('manual_trigger_key');
Triggering after initialization
Because Expoints loads asynchronously, trigger only after initialization is complete.
Use the optional callback in start:
expoints('start', 'configId', {
instanceUrl: 'https://<customer#>.expoints.nl'
}, onExpointsReady);
function onExpointsReady() {
expoints.trigger('manual_trigger_key');
}
Inline questionnaires
Inline questionnaires render inside a container on your page instead of opening as an overlay.
Configure a valid CSS selector in Expoints, for example #ExpointsInlineSelector.
Override the inline selector per trigger
You can override the configured selector for a specific trigger call.
The second parameter (data) is optional.
expoints.trigger('manual_trigger_key', null, '#override_selector');
var data = [
{ id: 5, value: 'external' },
{ id: 7, value: 'process' }
];
expoints.trigger('manual_trigger_key', data, '#override_selector');
Single page application navigation
For Single Page Applications, notify Expoints whenever the route changes. This keeps URL-based targeting and page history accurate.
// Call after the URL changed expoints.routeEvent(window.location.href);
Example with a router hook:
router.afterEach(function (url) {
expoints.routeEvent(url);
});
Set customer data
Customer data lets you pass context such as segment, channel, or journey phase. Once set, this data is available for future trigger evaluations.
var data = [
{ id: 5, value: 'external' },
{ id: 7, value: 'process' }
];
expoints.setCustomerData(data, /* optional */ configId);
The id maps to a customer data column in Expoints.
Use configId only when you work with multiple active configurations.
To clear stored customer data:
expoints.resetCustomerData(/* optional */ configId);
Pass data during a manual trigger
var data = [
{ id: 5, value: 'external' },
{ id: 7, value: 'process' }
];
expoints.trigger('manual_trigger_key', data);
Multiple configurations
You can connect multiple Expoints configurations on one website, for example for multiple brands or business units.
Load the script once, start the first configuration, then register the second one in a callback:
<script type="text/javascript">
(function() {
var exp = document.createElement('script');
exp.type = 'text/javascript';
exp.async = true;
exp.onload = function() {
window.expoints = lightningjs.require('expoints', 'https://<customer#>.expoints.nl/m/Scripts/dist/expoints-external.min.js');
expoints('start', 'firstConfigId', { instanceUrl: 'https://customer1.expoints.nl' }, loadSecondConfiguration);
function loadSecondConfiguration() {
expoints.registerConfig('secondConfigId', { instanceUrl: 'https://customer2.expoints.nl' });
}
};
exp.src = 'https://<customer#>.expoints.nl/m/Scripts/dist/expoints-external-loader.min.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(exp, s);
})();
</script>
expoints.registerConfig(configId, options, /* optional */ callback);
Close a questionnaire programmatically
Close the active questionnaire at any time:
expoints.close();
This also dispatches the expoints_questionnaire_closed event.
Browser events
Expoints dispatches events on document.
Use these events for analytics, conversions, or custom UI workflows.
Available events:
expoints_answeredexpoints_questionnaire_finishedexpoints_questionnaire_openedexpoints_questionnaire_closed
Listening to events
document.addEventListener('expoints_questionnaire_finished', function (e) {
console.log(e.detail);
});
Question answered
Fired when a customer answers a question. For text answers, events are debounced, but your own analytics logic should still handle potential duplicate processing.
document.addEventListener('expoints_answered', function (e) {
console.log(e.detail);
});
e.detail example:
{
answer: null OR 'text answer',
baseQuestionId: -1,
customerId: 123456,
questionText: 'Example question',
scales: [] OR [
{
label: 'Answer option 1',
value: 1
},
{
label: 'Answer option 2',
value: 2
}
]
}
Questionnaire finished
Fired when the questionnaire is fully completed.
document.addEventListener('expoints_questionnaire_finished', function (e) {
console.log(e.detail);
});
e.detail example:
{
answers: [] OR (see 'Question Answered' structure),
customerData: [] OR [
{
customerDataColumnId: 1,
name: 'Name of customer data column 1',
value: 'Example value 1'
},
{
customerDataColumnId: 2,
name: 'Name of customer data column 2',
value: 'Example value 2'
}
],
customerId: 123456
}
Questionnaire opened
document.addEventListener('expoints_questionnaire_opened', function () {
console.log('Questionnaire opened');
});
Questionnaire closed
document.addEventListener('expoints_questionnaire_closed', function () {
console.log('Questionnaire closed');
});
Content security policy (CSP)
If your website uses a Content Security Policy, allow Expoints domains. Without these entries, Expoints scripts, iframes, or assets can be blocked by the browser.
If CSP is incomplete, browser errors may look like this:
Minimal CSP example
Starting with a strict baseline like:
default-src 'self';
Add at least the following directives (replace #customer):
connect-src https://#customer.expoints.nl; font-src https://#customer.expoints.nl https://cms.expoints.nl; frame-src https://#customer.expoints.nl; img-src https://#customer.expoints.nl; script-src https://#customer.expoints.nl; style-src 'unsafe-inline' https://#customer.expoints.nl;
LocalStorage
Expoints stores operational state in LocalStorage (not cookies). These keys support targeting logic and behavior across page visits.
| Name | Description | Example Value |
|---|---|---|
| expoints_external_pages_history | List of visited pages on the current website. Used in rules such as "visited this page before". | ["https://expoints.nl/example1.html", "https://expoints.nl/example2.html"] |
| expoints_external_website_visited | Boolean marker that indicates whether the visitor has left and returned to the website. | true |
| expoints_external_pages_visited_counter | Total number of visited pages by the visitor. | 3 |
| expoints_external_previous_url | Previously visited URL on the same website. | https://expoints.nl/example1.html |
| expoints_external_customer_questioned | Stores whether and when a visitor already received a questionnaire, to avoid over-surveying. | {"date":"2021-12-15T13:55:40.995Z", "questioned":true} |