Install the snippet
The two lines to paste, and where they go on WordPress, Shopify, Squarespace, Wix, Webflow, Odoo, Lovable and plain HTML.
The snippet is one script tag and one div. The div carries your widget id (it starts with w_) and is where the widget appears:
An example: replace w_YOUR_WIDGET_ID with your widget id from the dashboard, or copy the whole snippet from the widget's Install tab.
<script src="https://app.tileset.com/v1/tileset.js" async></script>
<div data-tileset="w_YOUR_WIDGET_ID"></div>
Copy the real one from the widget’s Install tab, never type the id by hand. Its Where do I paste this? list has the short steps for each site builder below. The script is loaded once per page; add one div per widget. Your site’s own code never calls the TileSet API and never holds a key.
Older snippets with data-sbe-widget in place of data-tileset keep working: there is nothing to change.
Where it goes
| Site builder | Where to paste | Guide |
|---|---|---|
| WordPress | A Custom HTML block | WordPress |
| Wix | An Embed HTML element, with both lines in it | Wix |
| Shopify | A Custom Liquid section | Shopify |
| Squarespace | A Code block | Squarespace |
| Webflow | A Code Embed element | Webflow |
| Odoo | An Embed Code block | Odoo |
| Lovable | Ask its agent, or paste the snippet into the page | Lovable |
| Hand-written HTML | Anywhere in the body | this page |
Check it works
- Open the live page, not an editor preview, since most editors do not run scripts. A widget loads when it comes within about 600 px of the screen, so one far down a long page, or in a hidden tab, makes no request until a visitor is nearly there (browsers without that feature load it at once). Its views are counted when it loads, so a widget nobody scrolls to is not counted. Once it loads, its tiles keep their shape while images arrive. A widget further down loads before it scrolls into view, so the page does not move under the visitor. For one near the top of a page, which can draw a moment after the page, a
min-heighton itsdivholds its place. - Let TileSet look for you. The widget’s Install tab has a Check my page field. Paste the address of the page and press Check: TileSet reads the page the way a visitor would. The same check appears under the snippet when you first set up, and the Widgets screen links to it for a widget that has not loaded on a page yet. A passed check marks the widget Installed on the Widgets screen, with the site it passed on, until a visitor’s page load shows it Live. On Wix the snippet sits in a box our server cannot read: open the published page once, then check, and the check passes on the widget’s own report from that page (Wix guide). The page must be reachable without a sign-in. The address you checked is remembered for that widget in this browser, and you can run up to 30 checks an hour. If your AI agent installed it, it can run the same check on the page URL.
- Read the result. It says whether the script is there, whether this widget’s
divis there and whether the widget serves items. When the script or thedivis missing, a Copy the missing line button copies exactly the line to add (with two missing, one button for the script and one for the widget), so you paste it as it is.
What a check can tell you
Each problem comes with a fix:
- A placeholder or invented id. The
divhasYOUR_WIDGET_IDor an id that is not a widget of yours. Copy the snippet from the widget’s Install tab. - The script is missing. Add the script tag once on the page. If the
divis there but the script is not, your page builder probably strips script tags from a content block: put the script in the site’s header or footer code area and keep thedivwhere the feed should show. - The id belongs to another widget. The page has a widget
div, but not this widget’s. Replace its id. - A login, a bot check or a firewall. The page turns away visitors without a browser, so it cannot be read. Check the page in a private window, or check a public page of the site.
- A local or private address. Check my page reads only public pages on the standard port: not
localhost, an IP address, a name likenas.localorintranet.corp, or an address with a port such as:8080. Publish the page and check its public address. - An old, cached page. If you just added the snippet, clear the page cache (a caching plugin, your host or a CDN) and check again.
- A page built in the browser. Lovable, React, Next and Vite pages add the widget after they load, so our server cannot read it in the page’s HTML. If the widget has loaded on that site in the past week, the check passes and says when it was seen. If not, it asks you to open the page once in your browser and check again: that load is what tells us the widget is there.
If nothing shows
- The
divneeds a real widget id from your dashboard. A placeholder renders nothing. - A deleted widget renders nothing, on purpose. It never shows an error box to your visitors.
- Optimization plugins that combine or delay scripts can stop the widget loading, because the script finds its own address from its URL. Exclude
tileset.jsfrom them (embed.json an older snippet). - If your site sets a content security policy, it must allow
https://app.tileset.comfor scripts, connections and images, allow inline styles, and allow images from the platforms you show. For YouTube in the lightbox it must also allow frames fromwww.youtube-nocookie.com, for Twitch in the lightbox fromplayer.twitch.tvandclips.twitch.tv, and for Kick in the lightbox fromplayer.kick.com. - Free widgets show a small “Shown with TileSet” link under them. See Plans and credits.
How TileSet keeps tileset.js safe
The script runs on your pages, so here is what protects it and what you can check yourself.
- It comes from TileSet itself.
tileset.jsand the parts it loads later (the lightbox, the Bento layout, the lightbox styles) are served fromhttps://app.tileset.com, the same place as your dashboard. There is no third-party CDN in between and no third-party code inside it. - A version in the address.
/v1/is a promise: updates inside version 1 never break a snippet you pasted. A change that would needs a new address (/v2/), so it can never reach your page on its own. Older snippets that loadembed.js(https://app.tileset.com/embed.jsorhttps://app.tileset.com/v1/embed.js) get exactly the same file and keep working: there is nothing to change. - Published hashes. The SHA-384 hash of every file is public at
https://app.tileset.com/v1/tileset-manifest.json, with a command to check what your browser or server receives. Every day TileSet checks that the files it serves still match the hashes of the version it deployed, and a mismatch is treated as an incident. - Checked before it ships. A release ships only from the main branch, after the full test suite, a security review and a size limit pass.
- Your content security policy only needs to allow
https://app.tileset.com:script-src https://app.tileset.com, plusconnect-src https://app.tileset.comandimg-srcforhttps://app.tileset.comand the platforms you show (see If nothing shows).
Why no integrity attribute on the snippet? An integrity hash pins exact bytes. On our next update every pasted snippet would stop loading, and until you pasted a new one your page would miss every fix, security fixes included. That is why live services such as Stripe.js do not offer one on their loader either. The published hashes and the daily check let your security team verify what runs, without freezing your site on an old version.