Tours and onboarding in an app built with AI
Built the app with Lovable, Bolt.new, v0, Replit, Cursor or Claude Code and now want new users to find their way? Paste one prompt, check that one file changed, publish — then build tours, checklists and upgrade prompts in Clew instead of prompting UI code.
- Time
- ● 5 minutes
- Who does it
- You and your AI assistant
- Steps
- 6
Step by step
- Step 01
Copy your snippet from Clew
Sign up or sign in to Clew and open Admin → Overview. The card “No signal from the widget yet.” shows your line with the real site key — click it to copy. Keep the key handy for step 3.

Step 1 · schematic illustration - Step 02
Open the project in a mode that edits files
- Claude Code: run
claudein the project folder. - Cursor: open the chat in Agent mode.
- Lovable, Bolt.new, v0: the project chat.
- Replit: Agent or Assistant.

Step 2 · schematic illustration - Claude Code: run
- Step 03
Paste the prompt with your key
Copy the prompt, replace
PASTE_YOUR_SITE_KEYwith your key and send it. The prompt names the right file for each stack, so the assistant won’t scatter the tag across components.Add the Clew onboarding widget to this app. Insert this exact tag so it loads once on every page, including after client-side route changes: <script src="https://tryclew.io/widget/PASTE_YOUR_SITE_KEY.js" async></script> Where to put it (pick what matches this project): - Plain HTML, React + Vite, Vue + Vite: index.html, right before </head> - Next.js App Router: app/layout.tsx, with next/script: <Script src="(same URL)" strategy="afterInteractive" /> inside <body> - Next.js Pages Router: pages/_app.tsx, the same next/script component - Nuxt 3: nuxt.config.ts, app.head.script: [{ src: "(same URL)", async: true }] - SvelteKit: src/app.html, right before %sveltekit.head% - Astro: the <head> of the shared layout - Anything else: the root HTML template or root layout rendered on every page Rules: - Use the URL exactly as given. Do not download the script, bundle it or install an npm package. - Add it in one place only, never inside a component that re-renders. - If the project sets a Content-Security-Policy, allow https://tryclew.io in script-src and connect-src. - Change nothing else, then show me the diff.
Step 3 · schematic illustration - Step 04
Check that one file changed
Read the diff before accepting it. Expect one file and one added line — or a small
<Script>block in Next.js — with your real key. If the assistant also edited components, installed packages or copied the script into the project, ask it to undo that and keep only the tag.
Step 4 · schematic illustration - Step 05
Publish or deploy
The tag works only on the deployed app. Press Publish or Deploy in Lovable, Bolt.new, v0 or Replit. In Claude Code or Cursor, commit and push as usual if your hosting deploys from git.

Step 5 · schematic illustration - Step 06
Make sure it works
Open the published app in a regular browser window, then go back to Admin → Overview in Clew. Within a minute the card turns green: “Widget is live.”

Step 6 · schematic illustration
Where the tag goes in each stack
Use this to check the assistant’s work. Replace the placeholder with your key.
| Stack | File | What is added |
|---|---|---|
| Plain HTML | index.html (every page) | The line before </head> |
| React + Vite, Vue + Vite | index.html in the project root | The line before </head> |
| Next.js App Router | app/layout.tsx | <Script src="https://tryclew.io/widget/PASTE_YOUR_SITE_KEY.js" strategy="afterInteractive" /> inside <body> |
| Next.js Pages Router | pages/_app.tsx | The same <Script> component |
| Nuxt 3 | nuxt.config.ts | app.head.script entry with src and async: true |
| SvelteKit | src/app.html | The line before %sveltekit.head% |
| Astro | shared layout | The line inside <head> |
What each tool usually generates
Lovable and Bolt.new projects are usually React + Vite, so the tag goes into index.html. v0 generates Next.js with the App Router: app/layout.tsx. Replit depends on the template. With Claude Code and Cursor the assistant reads your repository and picks the file from the list in the prompt.
Next: let the assistant build the tours too
The same assistant can keep going after the install. With the Clew MCP server (Pro and above), Claude Code, Cursor or Codex can list your tours, draft a new one from a sentence, publish it when you say so, read its stats and fix steps whose element moved. It takes a personal token from Admin → AI access (MCP) and one command.
What you can add with AI coding assistants — no developer
Once the line is installed, every format below is built in the Clew editor. These guides pair the install with a concrete example.
Troubleshooting and FAQ
Is it safe to paste my site key into an AI chat?
Yes. The site key is not a password: it is meant to be public and ends up in your page’s HTML. It cannot be used to edit tours or read your data.
The assistant installed an npm package or copied the script
Ask it to revert that. Clew is loaded from its own URL so that fixes and new features reach your app without a rebuild.
Will the tag survive the next AI edits?
Usually yes, since it lives in the root file. If Admin → Overview stops showing “Widget is live” after a big regeneration, send the prompt again.
The admin still says “No signal from the widget yet.”
Open a page of the live site in a regular browser window and reload the admin after a minute. If nothing changes: make sure the change is published, not just saved; check that the placeholder was replaced with your real key; open the browser developer tools, Network tab, and look for widget/…js — it must return status 200. A 404 there means the key is wrong.
My site has a Content Security Policy
Two directives, nothing else: script-src https://tryclew.io and connect-src https://tryclew.io. The widget uses no eval, no blob: URL and no worker, and it installs its stylesheet through the CSSOM rather than as markup, so style-src 'unsafe-inline' is not needed in Chrome, Edge, Firefox 101+ or Safari 16.4+. Older browsers fall back to a <style> element — if you still support them and your style-src has no 'unsafe-inline', tours render there without styling. Copy-paste: Content-Security-Policy: script-src 'self' https://tryclew.io; connect-src 'self' https://tryclew.io;
Can I pin the widget version and use <code>integrity=</code>?
Yes. The line in the guides — /widget/PASTE_YOUR_SITE_KEY.js — is the rolling one: it always serves the current widget, which is why it cannot carry a Subresource Integrity hash (the bytes change). Alongside it every release is also served at an immutable, content-hashed address. Ask https://tryclew.io/api/v1/widget-version?site=YOUR_KEY and you get back version, path and integrity; put those two in the tag: <script src="https://tryclew.io/widget/v/<version>/YOUR_KEY.js" integrity="sha384-…" crossorigin="anonymous" async></script>. A pinned URL never changes under you, so the browser refuses the file if a single byte differs. You then update the version when you choose — ask the same endpoint in your deploy script. Nothing else changes: tours are still published from the Clew editor without touching the site.
Will an ad blocker eat the widget?
No. Our domain is on none of the big lists — EasyList, EasyPrivacy, AdGuard, uBlock Origin — so tours, tooltips and checklists appear for visitors running a blocker like everyone else. Statistics are the delicate part: EasyPrivacy blocks every third-party ping request, so the widget sends its events as an ordinary request instead, which those lists let through. To be out of reach of custom blocklists entirely, serve the widget from your own domain: point https://your-site/clew/* at https://tryclew.io/* in your CDN or nginx and change the line to <script src="/clew/widget/YOUR_KEY.js" async></script>. The widget then asks the API under the same prefix and everything is first-party.
Does it work in single-page apps (React, Vue, Next.js)?
Yes. Load the line once, in the root HTML or root layout. The widget follows client-side route changes itself (History API and hash changes), so do not add it per route and do not fire it on a “History Change” trigger — a second copy is ignored, but it is wasted work.
What about cookie consent banners?
Clew stores a first-party cookie and localStorage entries to remember which tours a visitor has completed and to count completions. It sends no data to advertising networks. Whether it may run before consent is a decision for your privacy policy; if your consent tool blocks it until the visitor agrees, tours simply start after consent.
I use a caching or optimization plugin
Purge the cache after installing, otherwise visitors keep getting old pages without the line. If the plugin delays, combines or defers JavaScript (WP Rocket, LiteSpeed Cache, Autoptimize, Cloudflare Rocket Loader), exclude tryclew.io/widget from those optimizations.
Will it slow down my site?
No. The line has async: the browser downloads the widget in parallel and runs it without blocking the page. The widget has no dependencies.
Can my app tell Clew that an onboarding step is done?
Yes, and it is one line. A checklist item can carry a rule that ticks it without the visitor clicking anything: a page they reach, a click on an element you name with a CSS selector, or an event your own code fires — Clew.complete('invited'), where invited is the key you typed next to the item in the editor. Call it at the moment the thing is really done, for example after your API confirms the invite. It is safe to call at any time and returns false when no checklist with that key is on the page. The older global name TutorKit still works.
Other ways to install
Google Tag Manager
A Custom HTML tag on All Pages, a check in Preview, publish. For sites that already use GTM.
Open guide →No-codeWebsite builders & CMS
WordPress, Webflow, Shopify, Wix, Squarespace, Framer, Tilda or plain HTML: where the head code field is and what to press.
Open guide →CodeReact and Next.js apps
One line in index.html or the root layout, identify() after login and stable data-tour anchors. Vite, Create React App, Next.js.
Open guide →