C cenaly.com
Start free

My Website

One tag on your site: chat, popups, cookie banner, booking, appointments, ordering, help and legal pages

35 min read Open this screen in the demo
On this page 13

My Website: widgets on your own site

The My Website section is for those who already have a site. There's nothing to migrate to our storefront: you paste one line of code into your existing site, and after that you switch the products you need on with toggles in the admin panel.

Where to find it: Admin panel → Marketing → "My Website" (admin.cenaly.com).

It works on any platform where you can paste a <script>: WordPress, Tilda, Wix, Shopify, Webflow, Bitrix, InSales, OpenCart, a custom-built site, or a landing page builder.


Site address and install code#

The “🌐 Your site” block at the top of the section walks you through three steps — address → code on the site → check — and the main button always offers the next unfinished step. The first is your site address (for example, example.com): we use it to check the installation and to build the correct links inside the widgets.

The second is the install code — a single line:

<script src="https://cdn.cenaly.com/site/v1.js" data-domain="YOUR-DOMAIN" async></script>

Paste it once — into <head> or right before </body>. You won't need to touch the site's code again: which widgets run is set by toggles in the admin panel, not by tags on the page. Turn a widget on, and it appears on the site within a few minutes; turn it off, and it disappears.

If you previously pasted individual widget tags by hand, they'll keep working: the single loader sees them and won't start the same widget a second time.


In the "Installation Code" window there is a tab for each platform — with the same steps as below.

Every platform here has its own anchor, so you can send the link to whoever edits the site instead of retelling the steps: #html, #google-tag-manager, #wordpress, #tilda, #wix, #shopify, #webflow, #squarespace — for example, /en/docs/site-widgets#tilda.

What is true on every platform, so we don't repeat it in each block:

  • the tag goes in once for the whole site — into the shared template, not into a single page;
  • on website builders (Tilda, Wix, Webflow, Squarespace) the change stays in the editor until the site is published again;
  • check the live site, not the editor preview;
  • if a cache or a CDN sits in front of the site, purge it: both the visitor and our check may be served a stored copy of the page without the tag;
  • what the installation check will not see anyway — a separate breakdown below.

HTML#

Any site whose template you can edit: hand-written, a landing page, a static site generator.

  1. Copy the code line: Marketing → "My website".
  2. Paste it into <head> or before </body> of the site's shared template.
  3. No shared template (pages are separate files) — paste it into every page.
  4. Upload the change, open the site and press "Check installation".

Google Tag Manager#

The way to go when you have no access to the template but GTM is already on the site.

  1. Tags → New → type "Custom HTML".
  2. Paste the code line, trigger — "All Pages", save.
  3. Press "Publish": until the container version is published, the live site has no tag.

⚠️ A tag raised from GTM will never be detected by our "Check installation" — that is not a bug but a consequence of the method: “What the installation check does not see”. Open the site and look with your own eyes.

WordPress#

  1. The WordPress dashboard (your-site/wp-admin); administrator rights are required.
  2. The reliable way: Plugins → Add → any plugin that inserts code into the header/footer → paste the line into its Header field → save.
  3. Without a plugin: Appearance → Theme File Editor → header.php (before the closing </head>) or footer.php (before </body>) → "Update File".
  4. Open the site and press "Check installation".

⚠️ Edits to the parent theme's files are lost when the theme is updated — the WordPress documentation warns about this too. A code-insertion plugin or a child theme survives updates. If a caching plugin is installed (W3 Total Cache, WP Rocket and the like), purge the cache, otherwise the check will see an old copy of the page.

💡 You don't need a separate widget plugin: one tag brings all widgets in. The Cenaly Consent plugin is a different story — it installs the cookie-banner tag only (see Cookies and consent).

Tilda#

  1. In the project list open "Site Settings" of the right site (project settings, not page settings).
  2. Section "More" (in some accounts it is labelled "Code Injection") → the field "HTML code for the head section".
  3. Paste the line and save.
  4. Republish all pages of the project — otherwise the code stays in the editor only.
  5. Open the live site and press "Check installation".

💡 If you need the tag on a single page only, the same field exists in "Page Settings" → "Additional"; then republish that page.

Wix#

  1. The site must be published and the domain connected: that is Wix's own condition for custom code.
  2. Settings → Development & integrations → Custom Code.
  3. "+ Add Custom Code" → paste the line, give the snippet a clear name.
  4. Apply to All pages, load once, placement — Head. Save.
  5. Press Publish, open the live site and press "Check installation".

⚠️ Wix code snippets are tied to the domain: assign another domain to the site and the snippets are deleted — the tag has to be pasted again.

Shopify#

  1. Shopify admin → Online Store → Themes.
  2. On the theme "…" → Duplicate: the copy is your way back.
  3. There as well: "…" → Edit code.
  4. On the left, the Layout folder → the theme.liquid file → paste the line before the closing </head> (or before </body>) → Save.
  5. Open the storefront and press "Check installation".

⚠️ The edit belongs to the theme, not to the shop: switch or re-create the theme and you must paste the tag into the new one, otherwise the widgets disappear with the old theme. Shopify checkout pages are closed to arbitrary theme scripts — the widgets are meant for the storefront.

Webflow#

  1. Site settings of the project → the Custom code tab.
  2. The Head code field → paste the line and save. Only the script itself goes there: no html, head or body wrapper tags.
  3. Press Publish — custom code does not run in the editor or in preview.
  4. Open the published site and press "Check installation".

⚠️ Custom code fields in Webflow site settings are available on a paid Site plan. If you need a widget on one page only, a page has its own code fields in its settings.

Squarespace#

  1. Site panel → Website → Website Tools → Code Injection.
  2. The Header field (it goes into the <head> of every page) → paste the line → Save.
  3. Open the live site and press "Check installation".

⚠️ The Code Injection panel is available on the Core, Plus and Advanced plans and on some legacy Squarespace plans. A page Code Block is not a replacement: it puts the code inside one page, while widgets are needed across the whole site.

The steps are checked against the platforms' official help. If a platform renames a menu item, trust its help centre rather than us — and tell us, we'll fix it.


Twelve widgets#

Every widget is a separate card with a toggle and a settings gear. The data the widgets collect ends up in the usual sections of the admin panel — there is no need to set up a separate "inbox for the site".

Widget What the visitor sees Where the data goes Documentation
🍪 Cookies and consent A consent banner with categories and a settings screen Consent log, cookie declaration Cookies and consent
💬 Chat: AI assistant and operators A chat bubble on the page The "Guests" section of "Team chat" — together with WhatsApp, Telegram, email, Messenger/Instagram Chat with guests
💡 Popups and forms Promos, exit offers, email capture, timers Campaigns and their statistics Popups on your own site
📅 Table reservation The "Book a table" button The "Tables" section — reservations and the floor plan Table reservations
🗓️ Online booking The "Book now" button: service → specialist → time The "Appointments" section Appointment book
🛒 Online order The "Order" button, a cart and checkout on top of your own site The "Orders" section Online ordering on your own site
📚 Support center A "?" button with published help articles Articles go to "Articles and pages" (the "Help" group), help analytics — to the "Knowledge base" Support center
⚖️ Legal documents Links to, or the text of, your privacy policy, terms and the like Pages on our hosting; re-publishing updates the site by itself; configured right in the widget panel, without a wizard Legal documents
📞 Call from the site The "Call" button — a conversation straight from the browser, with no number to dial The "Calls" section: recording and analysis just like an ordinary call Call from the site
☎️ Callback A "Call me back" form with a choice of a convenient time The callback queue: the system dials the manager and the guest by itself; requests go to "Requests" and to the "Callbacks" tab of the "Customers" section Callback
➕ Multibutton A single floating button holding every contact channel at once Wherever the chosen channel leads; in the admin panel — click statistics by channel Multibutton
📈 Live storefront Badges with the number of orders, reservations and appointments over a period, and the average rating Shows anonymized aggregates of your own events and reviews Live storefront

The load order is not accidental: the cookie banner loads first among our widgets. The single asynchronous loader reads the settings first and cannot get ahead of analytics that the site has already started. If you need blocking before the trackers start, install the separate consent/v1.js tag first in <head>, without async and defer, as described in the article on consent. The multibutton comes after the aggregated widgets, and the "Live storefront" comes last: its badges take into account the buttons in the same corner.

The cookie banner on cenaly.ru has limitations: the consent log and CSV are not collected yet, the cookie scanner is unavailable, and the declaration is maintained manually. When the config is unavailable, the current version lifts the tracker block; after installation, check the banner and the page's actual requests. The full terms are in Cookies and consent.

The support center shows published articles, which you need to prepare in the "Articles and pages" section or publish from the knowledge base. The button does not create articles by itself. In help analytics, page events inside this panel belong to the "site" source; the "widget" source denotes the help tab in the chat.

Legal documents must first be published on our hosting. The widget shows the published versions as links, in a window, or as text on the page; re-publishing them in the admin panel updates them. This is not automatic tracking of changes in legislation.

The multibutton is not just a list of links: it has an inviting bubble ("Got a question?"), display conditions (on which pages, after how many seconds, on phones only or everywhere), a prepared first message for messengers, and its own click statistics by channel.

The "Live storefront" shows social proof based on your own data — orders, reservations and appointments — and does it honestly: there are no names or phone numbers in the badge, the events are aggregated, and stale ones stop being shown according to the venue's calendar (a venue that was closed yesterday does not "sell" yesterday's orders).

The "Popups and forms" card has a "✨ Create from template" button next to the toggle and the gear: it opens the same widget settings window, but straight to a gallery of ready-made scenarios — and saves nothing until you press "Done".

The "Legal documents" panel no longer sends you into a five-step wizard: the country, the set of documents, the questions about your business, your legal details and the language all sit on a single screen, autofill and preview are collapsed, and at the bottom there is a "Documents to publish: N" counter. An option that contradicts the answers you have already given is locked, with an explanation of exactly why.

Open hub windows live in the page address: a widget's gear writes ?widget=<widget>, and the installation code window writes ?panel=install. That means a link to a particular widget's settings can be sent to a colleague, and it survives F5 and the "back" button.

A toggle alone is not enough for every widget — some also need content:

  • Online booking appears on the site once the menu has at least one item of the "Service" type and booking is enabled (the same switch as for table reservations);
  • The support center turns on with the toggle right away, but without published articles it opens an empty help page — the widget settings show how many articles are published.

Reservation limitations. Right now the table reservation widget converts the chosen date and time in the guest's browser time zone. For a visitor from a different zone the time in the log may differ from the venue's expected time — check it when confirming. A message that the request has been sent also does not always mean that the server has already confirmed the reservation. If online booking reports a delay in confirmation, check the appointment book first: a repeat attempt may create a duplicate.

Verifying that it is off. After turning a widget off, check the site and reopen the settings once the data has refreshed. In the current version the toggle may go dark locally while the previous "on" state is kept on the server. If you need to stop a single widget urgently, remove its separate tag or contact support; removing the shared tag stops the whole set it was connecting at once.

Above the buttons of every card there are mini-statistics for 7 days: impressions, opens and a third number that depends on the widget (requests, orders, reservations, appointments, conversations, dialogues, clicks). "—" means there is no data at all yet, "0" means telemetry is there but there were no events; "More →" leads to the "Site widgets" dashboard.

The online order settings window has one more button for an external site — "🔔 Notify when back in stock": you pick a product and a variant from your own catalog, mark up the button on the page of the sold-out product, and the guest leaves an email, confirms it via a link and receives a single message when the product is back in stock. We do not read someone else's catalog and do not take stock levels from someone else's page — the product is linked manually. More on this in the article Online ordering on your own site.


Forms that already exist on your site#

The "📝 Forms that already exist on your site" block under the grid of cards is for the case of "the request form is already on the site, and nobody is going to change it". We neither replace it nor delay it: the form is submitted to your backend just as before, and a copy of the request lands in the admin panel.

A rule is a CSS selector for the form, the addresses of the "name / phone / email" fields (the value can be either simply a field name, for example phone, or a selector, input[name="tel"]), optional page masks and a toggle. There can be up to 10 rules per location, one rule per form. A rule without a form selector, or without a phone or an email, cannot be enabled — there is nothing for it to collect. Every row has a "Check" button: the server reads the page and reports whether the form was found, which of the rule's fields it contains and what field names it has at all.

What exactly is sent. Exactly three fields — name, phone, email — plus the page address without parameters and anchor. Input before "Submit" is pressed is not read, we add no validation or delays of our own, and a form that has failed the browser's own validation creates no request. The server suppresses a repeat of the same form with the same contact within 10 minutes; with simultaneous submissions or a failure to write the marker a duplicate is possible. The forms of our own widgets are not listened to.

Interception sends a copy of the request without waiting for the server's reply. If the network drops or the browser blocks the request, the copy may not arrive: there is currently no delivery queue for when the connection is restored. A repeat with the same contact on the same page is likewise suppressed until the page is reloaded. A "sent" mark means an interception attempt, while the actual arrival should be checked in the inbox.

Where to look. The "Requests" section and the "Requests" tab of the contact center — as the group "Forms on the site: ". Every such request carries an honest note: we see the "Submit" press, not the fate of the data on your backend.

⚠️ The "Check" button parses HTML without a browser: it will not see a form that JavaScript draws — whereas interception in the guest's browser will. The panel says so directly.


The “🔗 Action links and QR” block under the card grid builds a link that opens one specific action on your site: https://your-site/#cenaly=book — the reservation form, #cenaly=appointment:<service> — booking straight into a service, #cenaly=order:<product> — the product card, plus chat, callback, the help centre, a document (legal:<type>) and the multi-button fan. Such a link is usually printed as a QR code: on a table, on a receipt, on packaging, in offline ads.

How to build one: choose the action, optionally a specific object (a service or an item from the published menu, a published document) and “where you place it” — this sets the UTM tags for your analytics (utm_source=qr&utm_medium=<place>&utm_campaign=<action>; we do not read them). The output is a link with a “Copy” button and a QR code downloadable as PNG and SVG. The link's base is your site address; if none is set, our storefront. Every widget card has a short “🔗 Link” button with the action preselected.

Why a # hash rather than a ? parameter: third-party CMSs, cache plugins and CDNs strip unknown parameters and change the canonical address, while a hash is never sent to the server by the browser — it is guaranteed to reach our code. It is executed by the unified tag: it reads the hash once on load, removes it from the address and opens the widget once it has come up. Standalone widget tags do not read the hash.

The block warns before you print a batch: the action's widget is off, or no install code was found on the site at the last check. The link does not switch on what is off and does not substitute a missing document — in that case it simply does nothing: on a third-party site that beats an error. The same link also works on our storefront of the business, including the help centre, documents and the multi-button — the sticker is printed once, and the site may change.


The online booking widget in detail#

Settings live in the "Online Booking" card → gear icon: button color, its text, the screen corner, and the language. Right below the settings there's a ready-made code line just for this widget, in case you're installing only this one.

Language. The default is auto: the widget speaks the language of the page it sits on and knows 45 languages. Only the dictionary that's actually needed gets loaded, so this doesn't affect your site's speed. You can also pin one language in the list — for example, if the site is bilingual but you want bookings taken in just one language.

Links to a specific service or specialist. You can add attributes to the widget tag so the guest lands right on the step you need:

Attribute What it does
data-service="service id" the service is pre-selected — a "Book" button next to the service's description on your site. The id is shown next to the item in the "Menu" section
data-master="specialist id" the specialist is pre-selected — for a page about a specific specialist; the specialist's id is the same as the employee's id
data-open="true" the booking panel opens on its own, with no click on the button — for a dedicated "Book now" page

A stale id (the service was renamed, the specialist left) doesn't break the widget: it quietly shows the usual choice starting from the first step.

Fewer steps to a booking:

  • a single service or a single suitable specialist — the extra screen isn't shown;
  • the "⚡ Nearest: today 17:30" chip books in one tap, and the calendar opens on its own on the first day with free time;
  • the name, phone, and email are remembered on the guest's device: on a repeat booking the fields are already filled in, and the "Not you?" link clears them;
  • on a phone the panel opens full screen, and the booking button doesn't hide under the keyboard;
  • the widget can be used from the keyboard and reads correctly with a screen reader.

Email. The email field is optional; if the guest leaves an address, they get a letter with the visit details and a "Manage booking" link that lets them move or cancel the visit themselves. Details — in Appointment book.

What the widget brought in. In the appointment book, the "🌐 Website widget" button shows the funnel for 7, 30, or 90 days: how many times the button was seen, how many guests opened the panel, reached the contact step, and booked, and how many bookings were lost to a slot taken meanwhile. Bookings that came from the site carry a "From website" badge.


Installation check#

The "Check installation" button opens your site and reads the page's source HTML. Possible answers:

  • "Widget code found on the site" — the single tag is in place;
  • "Only individual widget tags found" — old individual snippets are working, there's no single tag;
  • "The code on the site belongs to a different location" — the tag carries someone else's data-domain (a common mistake with several venues);
  • "No widget code on this page" — no tag is visible.

⚠️ The check reads the source HTML of one page. If the tag is inserted in the browser by Google Tag Manager or another script, the check won't see it — that's not an error. What else stays outside the method is collected below in “What the installation check does not see”.

Once a week the same check re-runs on its own — for locations that have a site address, at least one widget enabled and whose previous check found the tag. A tag dies silently — the site moved to a new theme, a contractor shipped a layout without the snippet, a cache plugin threw out the “extra” script — and before, the only way to notice was that the leads had stopped. Now the transition “tag was there → tag is gone” arrives as a card in the team chat (no more than once a week per location) and as a red third step in the “Your site” block. A site that did not open (timeout, server error) is not counted as broken — we will check again next week; a tag inserted through Google Tag Manager is never seen by the check, so there will be no false alarm for it either.

The same analysis is available publicly, without signing in — the Site check page: paste an address and it reads the page HTML and shows analytics and ad pixels by name, whether a consent banner is installed (ours, another vendor’s, or none), and whether our tag with its enabled widgets is visible. Handy for checking a site before connecting it, and for handing a link to a developer or a client.

Below the widget cards, the section has two more blocks: "Storefront on your own code (Headless)" — data, an API, and webhooks for when your own developer builds the site and doesn't need our widgets — and "Advanced: a separate tag per widget" with ready-made individual tags. So an individual tag isn't only something you "carry over from the past" — you can also take one right here.

What the installation check does not see#

The method is simple and honest: one request for the source HTML of one address, with no browser. We read what the server returned and look for <script src="…"> with our paths in the markup. Hence the whole list of what it cannot do — this is the boundary of the method, not a defect.

Case What the check will say How to find out for real
The tag is inserted by Google Tag Manager or any other script in the browser "no code" Open the site: the widget is either there or not. In developer tools, the Network tab, filter site/v1.js
Another page of the site: the tag is in the home-page template but not on blog or catalogue pages an answer about the address that is in the "site address" field Put the full address of an inner page into the field and run the check again
SPA (React, Vue and similar with client-side rendering): the markup is assembled by JS in the browser "no code", even when the widget works on the site Look with your own eyes. It is safer to put the tag into the server template or index.html rather than inside the app
Navigation inside an SPA without a page reload nothing: the check does not click through the site and only sees the first server response Walk through the sections yourself — the widget lives on the page and survives such transitions
The site answers over http:// only, or is behind a login, an IP filter or anti-bot protection a check error The check only goes over https and without authentication; look at such a site yourself
A very large page the first 512 KB of markup are read The tag belongs in <head> of the template — that puts it at the start of the page
More than three redirects in a row an error Enter the final address
A platform or CDN cache serves a stored copy without the tag "no code" Purge the cache and repeat
The tag is there but the widget does not work (not paid for, toggle off, display conditions kicked in) "code found" That is a different question — see "Troubleshooting" below

What the check does see well: whether our tag is in the source markup, whether it is the single loader or a set of individual tags, and whose data-domain it carries — that is, it catches the most common mistake, "copied the code from a neighbouring location".

The public Site check page has exactly the same boundary: it reads the source HTML and does not execute scripts. Real cookies and everything loaded in the browser are collected only by the CMP scanner — see Cookies and consent.


Troubleshooting#

A general list for all twelve widgets — from the most common cause to the rarest. Specifics of a particular widget are covered in its own article.

1. "Check installation" says there's no code. The tag isn't inserted, it isn't inserted on every template page, or the site hasn't been republished after inserting it (Tilda, Wix, Webflow require republishing). Also check the site address in the section header: the check runs against exactly that address — and against that one page only. Before fixing anything, go through “What the installation check does not see”: half of the "no code" answers are the boundary of the method, not a broken site.

2. The code on the site belongs to a different location. The tag carries someone else's data-domain — a common mistake when there are several venues and the code was copied from a neighboring card. Take the code with the right location selected.

3. The check doesn't see a tag inserted through Google Tag Manager. That's not an error. The check reads the page's source HTML — what the server actually returned — while GTM inserts the tag only in the browser. Open the site and look with your own eyes: the widget is either there or not. The full list of what the method does not show (GTM, another page of the site, an SPA, a closed site) — “What the installation check does not see”.

4. Changes haven't shown up on the site. Widget files are served through a CDN with a 5-minute cache. After flipping the toggle or changing the settings, wait a few minutes and reload the page with the cache cleared (Ctrl+F5). If the browser keeps showing the old version, check in an incognito window.

5. The widget is on, but it's not visible on the page. Go through the list:

  • the widget is a paid add-on and hasn't been paid for — an unpaid add-on is stripped from the site's data on the server, so it will not reach the page even with the toggle on;
  • the widget has display conditions (multibutton, callback, "Live Showcase"): a page mask, a delay, a device filter, or a schedule may have filtered out exactly this page and this moment;
  • the widget is missing content: online booking appears once the menu has at least one service item and booking is enabled; the help center opens an empty panel without published articles; multibutton isn't drawn at all without a single channel; "Live Showcase" stays silent while the numbers are below the threshold;
  • multibutton has absorbed a neighboring button: if its fan menu has an "Open chat" or "Callback" item, those widgets' own buttons are deliberately muted — they're now inside the fan menu.

6. Several buttons are crowding the corner of the screen. Turn on multibutton and add the actions of the widgets you need to its fan menu — their separate buttons will go dark on their own.

7. There are no widgets on a site built with our website builder. There, the install code is baked into the template, and the code block doesn't appear in the admin panel — that's normal. Check the widget toggles instead: a freshly generated site arrives with the cookie banner, legal documents, and chat already on; everything else needs to be switched on manually. Also note the difference between surfaces: on our storefront, multibutton shows only via a separate "Also show on our storefront" toggle (it absorbs the page's native buttons there), while "Live Showcase" works off the same single toggle as on someone else's site.


A site with Content-Security-Policy#

If your server sends a Content-Security-Policy header, the browser itself decides what our installation code is allowed to load. The tag itself works — you allowed it — but everything it pulls in may be blocked silently: from the outside it looks like "the widgets are gone". The browser console, meanwhile, shows lines like Refused to load the script.

The break happens in exactly one mode: the policy allows scripts only by a one-time nonce, without 'strict-dynamic' and without our CDN host in the list. Below are three ways to close that gap, starting with the simplest.

Option 1 — a nonce on our tag#

Your server generates a new random value for every response and puts it both in the header and in the tag:

Content-Security-Policy: script-src 'nonce-r4nd0m...'
<script nonce="r4nd0m..." src="https://cdn.<your brand>/site/v1.js" data-domain="YOUR-LOCATION" async></script>

The single tag reads the nonce of its own tag and passes it to every widget bundle it inserts — so they pass the script-src check. Requests, styles and embedded pages also need the permissions from the table below. The separate "Notify when back in stock" form has a limitation described below.

⚠️ A permanent value, the same in every response, is not a nonce: anyone who manages to inject code into the page will copy it into their own script. Generate it for every response, on the server.

Option 2 — 'strict-dynamic'#

Content-Security-Policy: script-src 'nonce-r4nd0m...' 'strict-dynamic'

With 'strict-dynamic', the trust placed in our tag extends to the scripts it inserts, including the lazy parts of "Smart popups". This is an example of a directive for scripts: if default-src, connect-src, style-src or frame-src are restricted, add the corresponding permissions from the table below.

Option 3 — a list of hosts#

If a nonce is not available to you (this happens on website builders), allow our hosts explicitly:

Content-Security-Policy: script-src https://cdn.<your brand>;
  connect-src https://cdn.<your brand> https://api.<your brand> wss://ws.<your brand> https://o.<your brand>;
  img-src https://cdn.<your brand> https://i.<your brand>;
  frame-src https://cdn.<your brand> https://your-location.<your brand>;
  style-src 'unsafe-inline'

A ready-made snippet with the hosts of your brand and your location already substituted is available in the admin panel: Marketing → My site, the "A site with Content-Security-Policy?" block under the installation code — the "Copy" button is there as well, along with a note on which widget needs each host.

What is needed and by whom:

Directive Who needs it
script-src All widgets: bundles from our CDN
connect-src All of them: requests, reservations, appointments, orders, telemetry; for the chat — the websocket and the signal bucket
img-src The order: photos of products and dishes
frame-src The order, the support center and legal documents: they open your storefront in an <iframe>
style-src All of them: widget windows insert <style> into their own Shadow DOM

What this does not cover — honestly#

  • Styles. The styling of the windows is an inline <style> inside the Shadow DOM, so style-src 'unsafe-inline' is required. This does not affect script-src: for scripts we ask for neither 'unsafe-inline' nor 'unsafe-eval'.
  • The lazy parts of the widgets (extended popups and the slots of "Smart popups", the age gate of the consent banner, the mobile bar of the multibutton, form interception) are loaded by their own loaders and do receive the nonce — they pass the same check as the main bundle. The exception is the form of the "Notify when back in stock" button (stock/form-v1.js): it is a separate tag outside the single loader, and it does not carry the nonce yet — under a nonce-only policy, without our CDN host, the subscription form will not open.
  • Website builders (Tilda, Wix and the like) send the header themselves, and you cannot issue a one-time nonce to your own tag there. That leaves the host-list option — if the platform lets you edit the policy at all.
  • Call from the site transmits audio as a WebRTC stream and does not load media files, so it does not need media-src; the microphone is allowed by Permissions-Policy and HTTPS, not by CSP.

Move a widget to its own section#

If one of the widgets is your main product (say, you only use popups or only the cookie banner), the path "Marketing → My Website → card → gear icon" is too long. Each card has a "Move to sidebar" button — the widget gets its own menu item and opens in one click.

This is a setting for your interface: it only controls the section's visibility, not how the widget runs on your site.

Site-wide settings — the address, the install code and the check — stay in "My Website": that item sits in the menu next to the widget's section, so a widget moved to the sidebar has no "← All website widgets" link. Remove the widget from the sidebar and the link comes back.

On the widget's own page the same button sits on the top frame of the settings block, on the right. For a widget in the sidebar it reads "In the sidebar" — click it to remove the item from the menu; the button stays where it is.


What is free and what is a paid extension#

Some widgets are included in the subscription, others are connected as an extension in the "Extensions" section: Reservations, Popups and forms, Support center and Legal documents are marked as paid — their card carries a "💳 Paid extension" chip.

A paid widget turns on after purchase. Pressing the toggle of an unpaid widget does not turn it on but opens the payment window right in the section; after payment the widget turns itself on. The "💳 Paid extension" chip on an unpaid widget is a payment button too, while on an already paid one it leads to the catalog to view the subscription. Access depends on an active purchase. Changing the subscription and updating the site settings are separate operations: if the widget has not appeared after the purchase, check the toggle and save the location settings. The five minutes of cache are counted from the publication of the updated data; a change of subscription status by itself does not currently guarantee such a publication.

On a site built with our website builder, "Legal documents" and the cookie banner are free. Their cards carry a "🎁 Included with the site" chip instead of "paid", and the payment window is not shown at all: this is not an upsell but the condition under which the site can be used lawfully. A newly generated site arrives right away with the cookie banner, the legal documents and the chat enabled. On an external site the "Legal documents" extension is paid for separately. In the current hub the cookie banner is not part of the list of the four paid widgets.

Pricing and payment are in the App store and Subscription sections.



FAQ#

Do I have to give up my own site? No. The widgets live on top of your site; you don't change your layout or hosting.

How many tags do I paste if I have several widgets? One. The set of widgets is toggles in the admin panel.

Will a widget slow down my site? The loader connects asynchronously (async) and doesn't block page rendering; each widget loads as its own small file, and only if it's enabled. A disabled widget isn't downloaded at all.

Will a widget break my layout? No. Every widget is drawn in an isolated container (Shadow DOM): your site's styles don't leak into the widget, and the widget's styles don't leak out. The one deliberate exception is the online ordering widget: it intentionally places "Add to cart" buttons in your own markup, and this is configured with a preview (see Online ordering on your own site).

What language will a widget speak? It looks at the page's language: first the data-lang attribute in the tag, if you've set one, then the lang of your HTML page, then the guest's browser language, and English as the last resort. Dictionaries vary in size: the cookie banner, the online booking widget and the chat window know 45 languages (the chat's labels arrive as a separate language pack matching the page language), and the rest ship with English, Russian, Georgian, and Turkish, falling back to English. You set the button labels and invitation text yourself — a separate line for each language of your site.

Where is the data the widgets collect stored? In your brand's cloud: AWS for cenaly.com, Yandex Cloud for cenaly.ru; data from Russian venues stays in Russia. Requests, orders, table reservations, and conversations land in your admin panel, while only the widgets' settings and things that are public anyway (the menu, opening hours, published documents, Live Showcase's anonymized numbers) go out to the public CDN.

I have several venues — how does that work? Widgets are configured per location: pick it in the list at the top of the section and take that location's install code. Each site has its own data-domain.

Can I put the widgets on several different sites? Yes, one location's tag can be pasted on several pages or sites — the data will arrive in that one location.

Was this article helpful?