Add an AI support assistant to a Next.js app
Two lines, one component, and no dependency added to your bundle.
- One component
- About two minutes
- One file
// app/layout.tsx — inside <body>, after {children}import Script from "next/script"; <Script id="matter-chat" strategy="afterInteractive"> {`window.MatterChat = window.MatterChat || { q: [] }; window.MatterChat.q.push(["init", { id: "bot_your_key" }]);`}</Script><Script src="https://app.matterchat.co/widget.js" strategy="afterInteractive" /></body>tsx · paste above the dimmed line
Where the snippet goes
Render it with next/script in your root layout, using the afterInteractive strategy. In the App Router that is app/layout.tsx; in the Pages Router it is pages/_app.tsx. The Script component handles deduplication across client-side navigation, so it initialises once and survives route changes.
- next/script, afterInteractive
- Loads after hydration, so it never competes with your app becoming interactive.
- Root layout, one place
- app/layout.tsx covers every route without per-page work.
- No npm dependency
- Nothing is added to your bundle — it is an external script, not a package.
- Survives soft navigation
- The Script component does not re-execute on client-side route changes.
Use next/script with afterInteractive. A bare script tag re-initialises on client-side navigation; the Script component deduplicates and survives route changes.
Index the docs you already deploy
If your documentation is part of the same app, or is a separate deployed site, the crawler reads it as published. There is no build step to add and no content to duplicate into another system.
Keep it out of the critical path
The script loads asynchronously, so it never blocks parsing or rendering. If you are measuring Core Web Vitals seriously, the afterInteractive strategy is the one that keeps a support widget out of your numbers — the plain async snippet can still fetch inside the critical window.
Checking it actually worked
Four things, in order. The third is the one people skip, and it is the one that tells you whether the answers are grounded.
- 1Hard refresh the page — the launcher appears bottom-right.
- 2Ask it something your site answers, and check the reply cites a page.
- 3Ask it something your site does not cover, and check it declines.
- 4Open Conversations in the dashboard; both should be there.
On a different stack?
The snippet is the same everywhere. Only the place you paste it changes.
What developers ask
Short answers. If yours is not here, the assistant on this page will try it — and tell you honestly if it cannot.
Does it work with the App Router?
Yes — render it from app/layout.tsx with next/script. It works the same way in the Pages Router from pages/_app.tsx.
Is there an npm package?
No, and that is intentional. It is a script tag, so nothing enters your bundle and there is no dependency to keep on a version treadmill.
Will it break on client-side navigation?
No. Loading it through next/script means it initialises once and is not re-executed when the router navigates.
From the blog
All posts- BuildingDomain locks and why “works on localhost” isn’t enoughDomain allowlists exist so your bot answers only where you installed it. Testing on localhost proves the script loads; it does not prove production embeds are locked down.Read
- EvaluatingThe best AI chatbot for a Webflow site, compared honestly (2026)Matter Chat, Social Intents, Ultimo Bots, Chatling, WeblyChat and Chatbase on a Webflow site: Apps marketplace or custom code, the paid-site-plan gate, CMS coverage, citations, handoff and pricing. Checked on the vendors' own pages.Read
- BuildingWhat to index first when your site is a messStart with the pages that already resolve real support questions. Noise, archives, and unfinished docs can wait — indexing them first makes answers worse.Read
Answer honestly. Capture the rest.
Point Matter Chat at your site and see what it can — and can't — answer. It's honest about both.
No credit card. 2 minute setup.
Every answer cites the source it came from. When there isn't one, it says so — and hands the visitor to you.
Installs on the tools you already run.