Website feedback tool for React and Next.js

Collect feedback on React, Next.js and Vue apps: load the snippet in your layout, enable it in staging only, get bug reports with browser context.

In short

In React, Next.js or Vue projects you load the nootiz snippet in the root layout or document and gate it behind an environment variable so it only runs in staging and preview deployments. Client and QA feedback then lands on the rendered component – with URL, browser and screen size attached.

Install in 3 steps

  1. 1

    Add the snippet to your root layout: app/layout.tsx for the Next.js App Router, pages/_document.tsx for the Pages Router, or the central index.html/app root for plain React.

  2. 2

    Decide how it loads: a plain <script> tag in <head>, or next/script with the „afterInteractive“ strategy so it doesn't block rendering.

  3. 3

    Gate it behind an environment variable (e.g. NEXT_PUBLIC_ENABLE_NOOTIZ) so the snippet only loads in preview and staging deployments.

  4. 4

    Trigger a deployment (a Vercel, Netlify or Cloudflare preview for the pull request) and open the generated preview URL to verify the snippet.

  5. 5

    Share the preview URL with client and QA and collect notes right on the rendered component.

What to watch out for

App Router or Pages Router: where exactly do you load the snippet?

In the Next.js App Router, the snippet belongs in the root app/layout.tsx so it loads on every route without repeating it in each page.tsx. In the classic Pages Router, add it instead to pages/_document.tsx inside the <Head> section, because _app.tsx re-runs on every client-side navigation and could otherwise include the script multiple times. In plain React without a framework, a <script> tag in the public/index.html is enough. In all three cases the snippet stays active regardless of which route the user is currently on.

Client-side routing and dynamic content

In single-page apps the view changes without a full reload, since the router only swaps parts of the DOM. nootiz records the current URL, including query parameters, with every note, so a route's state stays reliably reproducible. For content that loads after the initial render via a fetch call – a product list or a dashboard widget, for example – the note simply attaches to the element the user actually sees at the moment of feedback, regardless of when it loaded.

How do you load the snippet without hurting load time?

In Next.js, next/script with the „afterInteractive“ strategy is the recommended approach: the snippet loads once the page has become interactive, so it blocks neither the first render nor your Core Web Vitals. In plain React, an async or defer attribute on the <script> tag achieves the same effect. In practice the load-time difference between a version with and without nootiz becomes unmeasurable, which matters especially on performance-sensitive marketing pages.

Per-pull-request preview deployments

Vercel, Netlify and Cloudflare Pages create a dedicated preview URL with a full build for every pull request by default. With the snippet in your root layout, feedback works in every one of those previews immediately – no extra setup per branch and no reviewers manually pasting screenshots into tickets. This is especially useful for design reviews before merging, since product owners and clients comment directly on the real rendered version instead of a Figma export.

Loading it in staging only: how do you keep production clean?

If the tool is only used for internal sign-off and QA, simply leave the snippet out of production and only serve it when an environment variable like NEXT_PUBLIC_ENABLE_NOOTIZ, or a check like process.env.VERCEL_ENV === 'preview', evaluates to true. That keeps your production bundle marginally smaller and end users never see a feedback icon, while preview and staging deployments keep working unchanged.

Do clients need a GitHub or Vercel account to comment?

No. Clients and stakeholders just open the shared preview or staging URL in their browser and place notes there, with no repository access, no Vercel team membership and no need to understand branches or deployments. That's the key advantage over plain code-review comments on pull requests, which require technical understanding and usually stay out of reach for non-technical participants.

Where are the honest limits in React and Next.js setups?

Server Components, which never execute in the browser, obviously cannot embed the snippet themselves – it always has to load through a client component or the root layout that ships server-rendered HTML to the browser. With very aggressive preloading or prefetching of individual routes, there can occasionally be a brief moment where an element in a not-yet-fully-hydrated component isn't clickable yet; waiting a moment after the route change reliably resolves that.

Frequently asked questions

Does nootiz work with client-side routing?

Yes. Every note stores the URL and the element it was placed on.

Can I enable the snippet in staging only?

Yes, through an environment variable in your layout.

Is there an npm package?

The script snippet is all you need – that keeps you independent of framework versions.

Does the snippet affect Core Web Vitals?

It loads asynchronously and does not block rendering. In production you can also disable it with an env flag.

Does it work with Server Components and the App Router?

Yes. The snippet runs in the browser against the rendered DOM, regardless of server or client rendering.

How do notes reach our ticket system?

Through the Trello, Asana, Jira and GitHub integrations – including URL, element and browser context.

Other platforms

Stop collecting feedback in email threads

Add the snippet, share the link, collect feedback right on the page – live in under 5 minutes.