Compatible with both App Router (Next.js 13+) and Pages Router.
Add the script in your root layout:
import Script from 'next/script'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
{children}
{/* tokwork Widget */}
<Script
src="https://js.tokwork.com/loader.js"
data-website-id="YOUR_WEBSITE_ID"
data-website-domain="yourdomain.com"
strategy="afterInteractive"
/>
</body>
</html>
)
}
For more control, use the metadata API:
export const metadata = {
// ... other metadata
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
{children}
<script
async
src="https://js.tokwork.com/loader.js"
data-website-id="YOUR_WEBSITE_ID"
data-website-domain="yourdomain.com"
/>
</body>
</html>
)
}
import { Html, Head, Main, NextScript } from 'next/document'
import Script from 'next/script'
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
{/* tokwork Widget */}
<Script
src="https://js.tokwork.com/loader.js"
data-website-id="YOUR_WEBSITE_ID"
data-website-domain="yourdomain.com"
strategy="afterInteractive"
/>
</body>
</Html>
)
}
For better management, use environment variables:
NEXT_PUBLIC_TOKWORK_WEBSITE_ID=your-website-id
NEXT_PUBLIC_TOKWORK_DOMAIN=yourdomain.com
Then use them in your code:
<Script
src="https://js.tokwork.com/loader.js"
data-website-id={process.env.NEXT_PUBLIC_TOKWORK_WEBSITE_ID}
data-website-domain={process.env.NEXT_PUBLIC_TOKWORK_DOMAIN}
strategy="afterInteractive"
/>
Choose the right strategy for your needs:
afterInteractive (Recommended) - Load after page becomes interactivelazyOnload - Load during idle timebeforeInteractive - Load before page becomes interactive (not recommended)npm run dev✅ tokwork Widget loaded successfullyAdd type definitions if needed:
declare global {
interface Window {
WOM_WIDGET_CONFIG?: Array<{
websiteId: string
backendUrl?: string
}>
}
}