DEV Community

Hauke J.
Hauke J.

Posted on

Add a Feedback Widget to Your Next.js App in 5 Minutes

You shipped a Next.js app. Users are visiting. When something breaks, they just leave. No email, no bug report, no context about what they were doing when it broke.

This guide adds a floating feedback button to every page. Users can screenshot, annotate, and submit without leaving the page. One script tag, no npm packages, App Router and Pages Router both supported.

What you're adding

SeggWat is a feedback widget your users can:

  • Click on any page (it's a floating button)
  • Use to capture their viewport, then annotate with arrows, rectangles, text, and a blackout tool for sensitive bits
  • Use to file bug reports, feature requests, or general praise (each gets categorized)
  • Pin to a specific release via version tracking
  • Trigger without dropping a single cookie. GDPR-friendly, EU-hosted.

Submissions land in a dashboard with Kanban triage, analytics, and an Ideas Portal where users can vote on features.

Prerequisites

  • A Next.js project (App Router or Pages Router, both work)
  • A free SeggWat account (14-day trial, no credit card)
  • Your project key from the SeggWat dashboard

Option 1: App Router (Next.js 13+)

The cleanest place for the script is your root layout. That puts the button on every page without duplication.

Step 1: Add the script to your root layout

Open app/layout.tsx and load SeggWat through Next.js's built-in <Script> component:

// app/layout.tsx
import Script from 'next/script';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        {children}

        <Script
          src="https://seggwat.com/static/widgets/v1/seggwat-feedback.js"
          data-project-key="YOUR_PROJECT_KEY"
          data-enable-screenshots="true"
          data-button-position="bottom-right"
          data-button-color="#6366f1"
          strategy="afterInteractive"
        />
      </body>
    </html>
  );
}
Enter fullscreen mode Exit fullscreen mode

That's it. Every page in your app now has a feedback button.

Step 2: Tag feedback with your app version (optional)

If you want to know which release a bug was reported against, set data-version. Read it from package.json or an environment variable:

<Script
  src="https://seggwat.com/static/widgets/v1/seggwat-feedback.js"
  data-project-key="YOUR_PROJECT_KEY"
  data-enable-screenshots="true"
  data-version={process.env.NEXT_PUBLIC_APP_VERSION || "0.1.0"}
  strategy="afterInteractive"
/>
Enter fullscreen mode Exit fullscreen mode

Every submission is now tagged with the running release.

Step 3: Identify logged-in users (optional)

If your users are authenticated, link feedback to their identity with setUser(). Drop this in a client component:

// components/SeggWatUser.tsx
'use client';

import { useEffect } from 'react';
import { useSession } from 'next-auth/react'; // or your auth provider

export function SeggWatUser() {
  const { data: session } = useSession();

  useEffect(() => {
    if (session?.user && window.SeggwatFeedback) {
      window.SeggwatFeedback.setUser(session.user.id);
    }
  }, [session]);

  return null;
}
Enter fullscreen mode Exit fullscreen mode

Render <SeggWatUser /> in your layout next to the script.

Option 2: Pages Router

Pages Router users add the script to _app.tsx:

// pages/_app.tsx
import type { AppProps } from 'next/app';
import Script from 'next/script';

export default function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <Component {...pageProps} />

      <Script
        src="https://seggwat.com/static/widgets/v1/seggwat-feedback.js"
        data-project-key="YOUR_PROJECT_KEY"
        data-enable-screenshots="true"
        data-button-position="bottom-right"
        data-button-color="#6366f1"
        strategy="afterInteractive"
      />
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Same result, same one tag.

Adding more widgets

SeggWat ships several widget types. Here are the others worth knowing about.

Helpful rating (great for docs)

If you have a /docs section, drop a "Was this page helpful?" prompt at the bottom:

// Only on docs pages
<Script
  src="https://seggwat.com/static/widgets/v1/seggwat-helpful.js"
  data-project-key="YOUR_PROJECT_KEY"
  data-container="#helpful-container"
  strategy="afterInteractive"
/>

// In your docs component:
<div id="helpful-container" />
Enter fullscreen mode Exit fullscreen mode

Star rating (product pages, features)

<Script
  src="https://seggwat.com/static/widgets/v1/seggwat-rating.js"
  data-project-key="YOUR_PROJECT_KEY"
  data-container="#rating-container"
  data-style="stars"
  data-max-stars="5"
  strategy="afterInteractive"
/>
Enter fullscreen mode Exit fullscreen mode

The same widget supports a smiley variant via data-style="smiley" if stars aren't your aesthetic.

NPS survey

<Script
  src="https://seggwat.com/static/widgets/v1/seggwat-nps.js"
  data-project-key="YOUR_PROJECT_KEY"
  data-mode="banner"
  strategy="afterInteractive"
/>
Enter fullscreen mode Exit fullscreen mode

NPS only fires when its triggers match (URL pattern, custom event, or time-on-page), and respects per-visitor cooldown so you don't hammer the same person twice.

Customization cheat sheet

Everything is configured through data- attributes. No CSS overrides.

Attribute Values Default
data-button-position bottom-right, right-side, icon-only bottom-right
data-button-color Any hex color #2563eb
data-enable-screenshots true / false false
data-version Any string (none)
data-language en, de, sv Auto-detect
data-show-powered-by true / false true

Dark mode

The widget watches prefers-color-scheme and matches the user's system preference. No setting required.

Why this works well in Next.js

A few things worth flagging:

  1. strategy="afterInteractive" defers loading until after hydration, so the widget doesn't drag down your Lighthouse score.
  2. The widget is a vanilla script, not a React component, so it sidesteps server components and streaming SSR entirely. No hydration mismatches.
  3. Static export (output: 'export') works fine. The script loads from a CDN at runtime.
  4. Edge Runtime is fine for the same reason. Everything happens client-side.

What you get in the dashboard

Once submissions roll in:

  • A live feed that updates as feedback arrives
  • A Kanban board for triage: New, Active, Assigned, Resolved, Closed
  • Trend charts by type and over time
  • An Ideas Portal where users upvote feature requests (auto-populated from feedback)
  • GitHub integration: turn an idea into an issue, status syncs both ways

Quick comparison

Feature SeggWat Hotjar Canny Google Forms
In-page widget
Screenshot annotation
Idea voting portal
GDPR / EU-hosted ❌ (US) ❌ (US) ❌ (US)
No cookies
MCP server (AI-native)
Starting price $6/mo $32/mo $79/mo Free

Wrapping up

You've got a feedback widget on every page of your Next.js app. Users can screenshot bugs, request features, and rate pages without leaving their session.

About five minutes of work, ten lines of code, zero npm dependencies.

Next steps:


SeggWat is an EU-hosted, GDPR-compliant feedback tool built in Rust. No cookies, no tracking scripts, no data sold elsewhere. Try it free.

Top comments (0)