SaySift

Next.js Feedback Widget Integration Guide (App Router)

July 24, 2026

The SaySift widget is a plain <script> tag, which mostly means "just paste it in" — except in Next.js, where a raw <script> tag in a Server Component won't behave the way you expect. Use next/script instead.

App Router setup

In app/layout.tsx, add the widget with next/script's afterInteractive strategy so it loads without blocking the initial page render:

import Script from "next/script";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Script
          src="https://saysift.com/widget/feedback-widget.js"
          data-project-key="YOUR_PUBLIC_KEY"
          data-locale="auto"
          strategy="afterInteractive"
        />
      </body>
    </html>
  );
}

Putting it in the root layout means it's present on every route without adding it per-page. afterInteractive is the right strategy here — it loads after the page is interactive rather than blocking hydration, and the widget doesn't need to be in the initial HTML.

Opening it from a Client Component

The global window.SaySift object is only available in the browser, so any code that calls it needs to run in a Client Component:

"use client";

export function FeedbackButton() {
  return (
    <button onClick={() => window.SaySift?.open({ type: "bug" })}>
      Report a bug
    </button>
  );
}

The ?. matters — if this renders before the script has finished loading, window.SaySift won't exist yet. Listen for the saysift:loaded event on document if you need to guarantee it's ready before allowing the click.

Identifying logged-in users

If you're using a Next.js auth setup (NextAuth, Clerk, or your own), call identify() from a Client Component once the session resolves:

useEffect(() => {
  if (session?.user) {
    window.SaySift?.identify({
      externalId: session.user.id,
      traits: { name: session.user.name },
    });
  }
}, [session]);

That's the full integration for the App Router. Configuration attributes and the complete JavaScript API reference are in the widget documentation.

For the framework-agnostic version of this guide, see React Feedback Widget.

Start for free — no credit card required.

Confirm action

This action cannot be undone.