Skip to content
All posts

Add live chat to Next.js or Webflow

Next

Where to put the tkit.ai widget script in a Next.js app and in Webflow, and what to check before you call the install done.

By Sourabh SoniPublished

The widget does not care which builder rendered the page. It cares that the browser runs one script: https://cdn.tkit.ai/widget.js with your data-widget-id. Next.js and Webflow only differ in where that tag is allowed to live. The canonical snippet and the first-message test are in the install guide. This note is the placement detail those two stacks usually get wrong.

Use the id from the widget settings. your-widget-id in examples is a placeholder. Ids in the product are eight letters or numbers. The widget install check can read a paste locally before you deploy.

Next.js: one layout, the pages that should show it

Load the script from the root layout if every route should show the launcher, including docs and the marketing pages in the same app. Load it from a route-group layout if the logged-in product should not show the same greeting as the marketing site. Two widgets are allowed in one workspace. They do not have to share a greeting.

next/script with the afterInteractive strategy matches the install guide: the page becomes interactive, then the widget loads. async on the raw tag is the same idea when you are not using the Script component. Do not also paste the raw tag in head “just in case.” Two loaders means two launchers, or a race you will debug on a staging URL.

app/(marketing)/layout.tsx
import Script from "next/script";
 
export default function MarketingLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <>
      {children}
      <Script
        src="https://cdn.tkit.ai/widget.js"
        strategy="afterInteractive"
        data-widget-id="your-widget-id"
      />
    </>
  );
}

Replace the id. If the marketing site and the app are different deployments, each deployment gets the tag for its own widget, and each widget's allowed domains include only that host. A wildcard such as *.example.com covers subdomains. It does not cover a different registrable domain. Add that host explicitly.

A preview URL on a host you did not allow will not show the widget. That looks like a broken Script tag and is usually the domain list. Add the preview host while you test, and remove it if previews should stay quiet.

In Webflow, site-wide custom code in the footer is the usual place. Project settings, custom code, footer, then paste the script from your widget settings. Page-level custom code is the right choice when only the contact page or the docs should show chat. Publish the site. The designer canvas is not the test.

Webflow footer code
<script
  src="https://cdn.tkit.ai/widget.js"
  data-widget-id="your-widget-id"
  async
></script>

Webflow's published domain and your custom domain are different hosts. Allow both, or allow only the custom domain if the webflow.io host should not chat. The widget will not load on a host that is missing from the list, which is what you want if someone copies the HTML.

If the site is exported and hosted elsewhere, the footer code still has to be on the exported pages. An export that drops custom code is a missing script, not a Webflow mystery. The install check will say the tag is absent if you paste the page source.

The same checks on both

After the tag is on a page you are allowed to load:

  1. Open the published URL, not a file on disk.
  2. Confirm one launcher.
  3. Send a message and find it unread in the shared inbox.
  4. Reply from the inbox and confirm the widget shows it.

The testing checklist adds mobile layout, keyboard access, and what happens when the script fails. Do that before you announce the widget. Account creation does not ask for a credit card. Pricing is indicative and has no checkout.

What not to install

There is no npm package to add for the embed, and no Webflow app required by the snippet itself. If a tutorial tells you to wrap the loader in a chat SDK, skip it. The live chat widget page is the product description that matches this tag.

A second brand should be a second widget or a second workspace, not a second copy of the same id on an unrelated domain. The workspaces guide covers that split.