Disfora
Docs menu

Add comments to a Next.js site

Load the Disfora script once in your root layout with next/script, then put a container on the page that renders a post. Readers can click from post to post and each one shows its own thread.

Before you start

  • A Disfora project for your site. Create a free account, start a project and enter your domain. You'll verify it once the code is live.

App Router

Add the script to your root layout, app/layout.tsx:

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://disfora.com/public/disfora.js" strategy="afterInteractive" />
      </body>
    </html>
  );
}

Then add the container where comments should appear, for example after the post body in app/blog/[slug]/page.tsx:

app/blog/[slug]/page.tsx
export default async function Post({ params }: { params: Promise<{ slug: string }> }) {
  const { slug } = await params;
  const post = await getPost(slug);

  return (
    <article>
      <h1>{post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: post.html }} />
      <div data-disfora-comments />
    </article>
  );
}

The container is a plain element, so the page can stay a Server Component. You don't need 'use client'. For a star rating as well, add <div data-disfora-ratings /> where it should go.

Pages Router

Add the script to pages/_app.tsx, so it loads once for the whole app:

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://disfora.com/public/disfora.js" strategy="afterInteractive" />
    </>
  );
}

Then put <div data-disfora-comments /> in your post page, for example pages/blog/[slug].tsx.

<Link> changes the page without a reload. Disfora notices the new address and the new container, and loads that post's comments. Pages without a container, like your home page, show nothing, and the comments code only downloads once a reader opens a post. You don't need a key or any code that reloads the widget.

Each post's thread belongs to its address, so /blog/hello and /blog/hello?ref=twitter share one thread. See how pages are matched.

It works the same with a static export (output: 'export'): the script and container are plain HTML.

Check it on your site

Disfora only loads on the domain in your project, so localhost:3000 won't show it. Deploy, then verify your domain if you haven't yet, and open a post on your live site.

Ask a question

Something missing or unclear? Ask here and we'll answer in the thread.

Updated October 2026