Onsite uses pop-ups, banners, and referral widgets on your website to capture leads, to segment visitors, and to activate offers It taps into real-time behavior to make your site more dynamic and personal.
Here is how you configure and work with onsite messaging in Engage.
Prerequisites
Before you start you will need these things to be in place:
Access to GTM container
You’ll need access to your GTM container with publish permissions.
Access to your dataLayer or variables
You’ll also need access to your website’s dataLayer or variables for:
- Order totals and revenue
- Customer email addresses
- Currency codes
- Discount/coupon codes
Test environment
A test environment is needed to validate implementation
Voyado Chrome extension
And, optionally, the Voyado Chrome extension installed for testing
Implementation paths
Here we will consider three ways to implement Onsite:
- Via Google Tag Manager in SPAs (single page applications)
- Via Google Tag Manager in traditional multi-page applications
- Via direct implementation
1- Google Tag Manager - SPA
Single Page Applications require special handling because page navigation doesn’t trigger traditional page loads. For example, if your trigger uses custom pageload events, your exceptions must also use custom pageload events. Mixing event types (e.g., history change with pageview exceptions) will cause failures.
Other aspects of SPAs:
- Navigation happens without full page reloads
- Scripts must trigger on virtual page views
- Open widgets persist during navigation and must be explicitly closed
- All triggers must use consistent event types
You’ll need to create four tags. Suggested names are:
- Voyado Onsite Cornerwidget - Displays messaging widgets across the website
- Voyado Onsite Hide - Closes any open widgets on checkout/cart pages
- Voyado Onsite Purchase - Tracks conversions and displays messages on order confirmation page
- Voyado Onsite Login - Identifies user and enables personalized messaging onsite
Purpose: This loads and displays messaging widgets on landing pages and virtual page views.
Trigger: All pageviews EXCEPT checkout, cart, and order confirmation pages. Should also be excluded when the login script is called instead.
Voyado Onsite Cornerwidget Script
<script>
if (typeof redeal !== 'function') {
(function(i,s,o,g,r,a,m){i['RedealObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window, document, 'script', 'https://static.redeal.se/widget/js/redeal.js', 'redeal');
}
redeal('cornerwidget');
</script>
The (typeof redeal !== ‘function’) check prevents the script from being loaded multiple times on SPAs. The script loader only runs once, but redeal(‘cornerwidget’) can be called on each virtual page load.
Configuration in GTM:
- Tag Type: Custom HTML
- Trigger: Custom Event on page load
- Exceptions: Checkout page, Cart page, Order confirmation page and Login event
Alternative tag names:
Replace “cornerwidget” with any tag name configured in Onsite Manager. Use multiple tags with different conditions to trigger different onsite messages.
Tag 2: Voyado Onsite Hide
Purpose: Close open widgets when users navigate to pages where widgets shouldn’t appear (checkout, cart).
On SPAs, excluding pages from the “Voyado Onsite Cornerwidget” tag only prevents NEW widgets from loading; it doesn’t close widgets that are already open. This tag explicitly closes them.
Trigger: Pageview on checkout and cart pages.
Voyado Onsite Hide script
<script>
if(typeof redealHide === 'function') {
redealHide();
}
</script>
Configuration in GTM:
- Tag Type: Custom HTML
- Trigger: Custom Event on page load when Page Path contains “/checkout” or “/cart”
Tag 3: Voyado Onsite Purchase
Purpose: Track conversions and optionally trigger post-purchase onsite messages.
Trigger: Order confirmation page load (immediately after purchase).
Voyado Onsite Purchase script
<script>
if (typeof redeal !== 'function') {
(function(i,s,o,g,r,a,m){i['RedealObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window, document, 'script', 'https://static.redeal.se/widget/js/redeal.js', 'redeal');
}
if(typeof IsRedealOpen !== 'function' || !IsRedealOpen('checkout')) {
redeal('checkout', {
total: {{sumtotal}},
revenue: {{sumrevenue}},
currency: {{currencycode}},
email: {{userEmail}},
coupons: [{{discountcode}}]
});
}
</script>
| Variable Name | Type | Example value | Description |
|---|
| sumtotal | Data Layer Variable | ”113.75” | Total amount paid by customer (string) |
| sumrevenue | Data Layer Variable | ”93” | Revenue excluding tax and shipping (string) |
| currencycode | Data Layer Variable | ”SEK” | ISO currency code |
| userEmail | Data Layer Variable | ”john@doe.com” | Customer email address |
| discountcode | Data Layer Variable | ”aJ7q54JU” | Coupon/discount code used (can be array) |
Expected output:
redeal('checkout', {
total: "113.75",
revenue: "93",
currency: "SEK",
email: "john@doe.com",
coupons: ["aJ7q54JU"]
});
Important notes:
- total = full amount paid by customer (including tax, shipping, fees)
- revenue = amount excluding tax, shipping, and fees
- coupons should be an array even if there is only one code
- Missing or null values won’t break functionality but will limit tracking and reporting
- Optional fields: name, phone (useful for prefilling onsite messages and automatically identifying visitors)
Configuration in GTM:
- Tag Type: Custom HTML
- Trigger: Custom Event associated with reaching the order confirmation page, for example “purchase”, or when Page Path contains “/order-confirmation” or “/thank-you”
Tag 4: Voyado Onsite Login
Purpose: Identifying unidentified visitors and triggering personalized onsite messages
When to trigger:
- When a user actively logs in (login button click)
- On page load if user is already logged in (“soft login”)
Trigger: Login event OR pageview when user is authenticated
The login script should only be called once per session, and not on any subsequent page views after the login event occurs. On subsequent page views, calling the cornerwidget script instead is expected.
Voyado Onsite Login script
<script>
if (typeof redeal !== 'function') {
(function(i,s,o,g,r,a,m){i['RedealObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window, document, 'script', 'https://static.redeal.se/widget/js/redeal.js', 'redeal');
}
if(typeof IsRedealOpen !== 'function' || !IsRedealOpen('login')) {
redeal('login', {
email: {{userEmail}}
});
}
</script>
Required GTM Variables:
- userEmail - User’s email address (unhashed string)
Optional fields:
- phone: userPhone – User’s phone number
- contactId: contactID – User’s contact ID in Voyado Engage
Configuration in GTM:
- Tag Type: Custom HTML
- Trigger: Custom Event user_login OR first page view when User State = “logged_in”, expected to fire only once per session
Benefits:
- Enables automated consent updates via Reach Ability feature
- Triggers onsite messages to complete missing profile data
- Improves contact data quality
- Improves onsite scripts user identification
2 - Google Tag Manager (traditional)
For traditional multi-page applications (non-SPAs), the implementation is simpler because each page navigation is a full page load.
The main differences from the SPA implementation are:
- No need for the if (typeof redeal !== ‘function’) check
- No need for the Hide tag (widgets don’t persist across page loads)
Cornerwidget (Traditional Sites) script
<script>
(function(i,s,o,g,r,a,m){i['RedealObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window, document, 'script', 'https://static.redeal.se/widget/js/redeal.js', 'redeal');
redeal('cornerwidget');
</script>
Trigger: All Pages EXCEPT checkout and order confirmation.
Tag 2: Purchase (Traditional Sites)
Purchase (Traditional Sites) script
<script>
(function(i,s,o,g,r,a,m){i['RedealObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window, document, 'script', 'https://static.redeal.se/widget/js/redeal.js', 'redeal');
redeal('checkout', {
total: {{sumtotal}},
revenue: {{sumrevenue}},
currency: {{currencycode}},
email: {{userEmail}},
coupons: [{{discountcode}}]
});
</script>
Trigger: Order Confirmation Page
Tag 3: Login (Traditional Sites)
Login (Traditional Sites) script
<script>
(function(i,s,o,g,r,a,m){i['RedealObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window, document, 'script', 'https://static.redeal.se/widget/js/redeal.js', 'redeal');
redeal('login', {
email: {{userEmail}}
});
</script>
Trigger: Login success event OR first page view when user is authenticated
3 - Direct implementation
For sites without GTM, or when you want full control, you can add the script directly to your HTML.
Place this code immediately after the opening <body> tag on all pages where messaging should appear:
Direct implementation script
<script>
(function(i,s,o,g,r,a,m){i['RedealObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window, document, 'script', 'https://static.redeal.se/widget/js/redeal.js', 'redeal');
</script>
This loads the script asynchronously without blocking page rendering.
The individual tag types are implemented like this:
Cornerwidget (landing pages)
Cornerwidget (landing pages) script
<script>
(function(i,s,o,g,r,a,m){i['RedealObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window, document, 'script', 'https://static.redeal.se/widget/js/redeal.js', 'redeal');
redeal('cornerwidget');
</script>
With user prefill (when user data is available) you will use:
Cornerwidget (landing pages) with refill script
<script>
(function(i,s,o,g,r,a,m){i['RedealObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window, document, 'script', 'https://static.redeal.se/widget/js/redeal.js', 'redeal');
redeal('cornerwidget', {
email: "",
name: "",
phone: ""
});
</script>
Checkout (order confirmation page)
Checkout (order confirmation page) script
<script>
(function(i,s,o,g,r,a,m){i['RedealObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window, document, 'script', 'https://static.redeal.se/widget/js/redeal.js', 'redeal');
redeal('checkout', {
total: "",
revenue: "",
currency: "",
email: "",
coupons: []
});
</script>
Login (login page or when user is authenticated)
<script>
(function(i,s,o,g,r,a,m){i['RedealObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window, document, 'script', 'https://static.redeal.se/widget/js/redeal.js', 'redeal');
redeal('login', {
email: "",
phone: ""
});
</script>
Hide function (SPAs only)
// Call this when navigating to pages where widgets should be hidden
if(typeof redealHide === 'function') {
redealHide();
}
Script reference
Standard tag names
| Tag name | When to use | Recommended data |
|---|
| cornerwidget | Landing pages, general browsing | None (optional/if available: email, name, phone, contact ID) |
| checkout | Order confirmation/thank you page | total, revenue, currency, email, coupons |
| login | After user login or when authenticated | email (optional/alternative: phone, contact ID) |
| custom | Any custom trigger defined in Onsite Manager | Varies by onsite message |
Data field specifications
{
total: "113.75", // String: Total amount paid (including tax, shipping)
revenue: "93", // String: Revenue excluding tax and fees
currency: "SEK", // String: ISO 4217 currency code
email: "user@example.com", // String: Customer email
coupons: ["CODE123"], // Array: Discount codes used
name: "John Doe", // Optional String: Customer name
phone: "+46701234567", // Optional String: Customer phone
contactId: "b9a02dc6-52b8-4e11-b929-b37500f002f1" // Optional String: User's Contact ID in Engage
}
Cornerwidget fields (all optional)
{
email: "user@example.com",
name: "John Doe",
phone: "+46701234567",
contactId: "b9a02dc6-52b8-4e11-b929-b37500f002f1"
}
{
email: "user@example.com", // Optional: User email
phone: "+46701234567", // Optional: User phone
contactId: "b9a02dc6-52b8-4e11-b929-b37500f002f1" // Optional: User's Contact ID in Engage
}
It is optional which of the above field(s) to pass in the script call, but at least one needs to be passed for script identification upon login to work.
You can define custom tags in Onsite Manager and trigger them:
redeal('custom-tag-name');
Use case: Trigger different onsite messages based on user actions:
<button onclick="redeal('special-offer)">View Offer</button>
A/B Testing: If multiple onsite messages use the same script tag and fulfil any additional targeting criteria needed to be displayed, one will be randomly selected and displayed to the user.
Hide function
Basic usage (hide all open widgets):
Onsite message URL links
Each onsite message in Onsite Manager generates an onsite message URL link as well as a QR code. Use these links in emails or social media to drive traffic to your website and trigger the appropriate onsite messages automatically.
With personalization variables (for email marketing):
https://yoursite.com/onsite-message-url?email=*|EMAIL|*&name=*|NAME|*
Replace |EMAIL| and |NAME| with the merge tag format from your email service provider.
Domain matching
Onsite messages only trigger on domains configured in Onsite Manager.
Use these:
Production domain: www.example.com
Test subdomain: test.example.com
Do not use these:
Local development: localhost or 127.0.0.1
IP addresses: 192.168.1.100
For testing on non-production domains, add the test domain to your site configuration in Onsite Manager.