Install Flawsnap in a Next.js app
Use next/script in the root layout so the widget loads once for the whole app and survives client-side navigation.
Steps
- 1
Allow your hosts
In Flawsnap, add your production domain,
localhost:3000and the preview hosts you test on under Security → Allowed domains. - 2
Store the key
Add
NEXT_PUBLIC_FLAWSNAP_KEY=pk_…to.env.localand to your hosting provider’s environment variables. - 3
Add next/script to the root
App Router: add a
<Script>toapp/layout.tsx. Pages Router: add it topages/_app.tsx. Usestrategy="afterInteractive". - 4
Identify users in a client component
Add a small
'use client'component that callswindow.Flawsnap?.identify()when the session is known. - 5
Check it
Run
next dev, openlocalhost:3000, send a test report and confirm it lands in the project.
App Router: app/layout.tsx
The root layout renders once and stays mounted as people move between routes, which is exactly the lifetime the widget needs. next/script passes data-* props through to the tag.
import Script from 'next/script'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Script
src="https://backend.flawsnap.com/widget.js"
data-key={process.env.NEXT_PUBLIC_FLAWSNAP_KEY}
strategy="afterInteractive"
/>
</body>
</html>
)
}Pages Router: pages/_app.tsx
import type { AppProps } from 'next/app'
import Script from 'next/script'
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Script
src="https://backend.flawsnap.com/widget.js"
data-key={process.env.NEXT_PUBLIC_FLAWSNAP_KEY}
strategy="afterInteractive"
/>
<Component {...pageProps} />
</>
)
}Do not put the script in a page or a nested layout. It would load when that route first renders and be missing from the others.
Choosing the strategy
afterInteractive(recommended) loads the widget once the page is interactive. It does not compete with your own JavaScript for the first paint.beforeInteractiveloads it earlier, so errors during hydration are captured too. Next.js only allows it in the root layout (or_documenton the Pages Router).- Avoid
lazyOnloadhere: it waits for idle time, and a bug that happens early in the visit would have no console or network history.
Identify users from the session
window only exists in the browser, so identify from a client component rendered inside the layout. With NextAuth, for example:
'use client'
import { useEffect } from 'react'
import { useSession } from 'next-auth/react'
export function FlawsnapIdentify() {
const { data } = useSession()
useEffect(() => {
const u = data?.user
if (u?.email) window.Flawsnap?.identify({ name: u.name ?? '', email: u.email })
}, [data])
return null
}The window type
// flawsnap.d.ts (anywhere your tsconfig includes)
export {}
declare global {
interface Window {
Flawsnap?: {
open(): void
identify(reporter: { name?: string; email?: string }): void
setMetadata(details: Record<string, unknown>): void
screen(name: string): void
track(name: string): void
resetUser(): void
}
}
}Preview deployments and allowed domains
Each preview deployment on a platform such as Vercel gets its own host name. Flawsnap only accepts wildcards over a domain you own, and refuses them over shared hosting suffixes, so a wildcard over the platform’s domain is not the way to cover previews.
- List the exact preview host you are testing, such as a branch alias that stays the same between pushes.
- Or put previews on your own domain, such as
pr-42.preview.example.com, and allow*.preview.example.com. - Remember
localhost:3000fornext dev.
Troubleshooting
data-keyis empty in production:NEXT_PUBLIC_variables are fixed at build time. Set it in your host’s settings and rebuild.- The console says the widget is on the page twice: the
<Script>is in more than one layout. Keep only the root one. - A strict CSP set in
middleware.tsornext.config: allowhttps://backend.flawsnap.cominscript-srcandconnect-src.
Questions
- Does the widget work with server components?
- Yes. The
<Script>tag can sit in a server layout. Only code that toucheswindow.Flawsnap, such as identify, needs a client component. - Are route changes tracked in Insights?
- Yes. Insights (Pro) follows
pushStatenavigation, which is how the Next.js router changes pages, and records each path as a screen with ids masked.
Try it on your own site
7-day free trial, then $9 a month for Starter or $19 for Pro, per organization, with unlimited team members.
Related
Updated