Next.js Installation

Add Simple Commenter to your Next.js application using the built-in Script component. This guide covers both the App Router and Pages Router.

Important: The domain in your script must exactly match the domain you registered in your Simple Commenter dashboard. If they don't match, the widget won't load.

App Router (Next.js 13+)

Add the Script component to your root layout:

// app/layout.jsx
import Script from "next/script";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Script
          src="https://simplecommenter.com/js/comments.min.js?domain=your-domain.com"
          strategy="afterInteractive"
        />
      </body>
    </html>
  );
}

Replace your-domain.com with your actual domain from the Simple Commenter dashboard.

Pages Router

Add to your custom App component:

// pages/_app.jsx
import Script from "next/script";

export default function App({ Component, pageProps }) {
  return (
    <>
      <Component {...pageProps} />
      <Script
        src="https://simplecommenter.com/js/comments.min.js?domain=your-domain.com"
        strategy="afterInteractive"
      />
    </>
  );
}

Or add to your custom Document:

// pages/_document.jsx
import { Html, Head, Main, NextScript } from "next/document";
import Script from "next/script";

export default function Document() {
  return (
    <Html>
      <Head />
      <body>
        <Main />
        <NextScript />
        <Script
          src="https://simplecommenter.com/js/comments.min.js?domain=your-domain.com"
          strategy="beforeInteractive"
        />
      </body>
    </Html>
  );
}

Script Strategies

Next.js Script component supports different loading strategies:

StrategyDescriptionBest For
afterInteractiveLoads after page is interactiveMost cases (recommended)
lazyOnloadLoads during browser idle timePerformance-focused apps
beforeInteractiveLoads before page hydrationCritical scripts
// Recommended for most cases
<Script
  src="https://simplecommenter.com/js/comments.min.js?domain=your-domain.com"
  strategy="afterInteractive"
/>

// For better performance (slight delay)
<Script
  src="https://simplecommenter.com/js/comments.min.js?domain=your-domain.com"
  strategy="lazyOnload"
/>

Using Data Attribute

If you prefer the data-attribute method:

<Script
  src="https://simplecommenter.com/js/comments.min.js"
  data-domain="your-domain.com"
  strategy="afterInteractive"
/>

Environment Variables

Store your domain in environment variables:

# .env.local
NEXT_PUBLIC_SC_DOMAIN=your-domain.com
// app/layout.jsx or pages/_app.jsx
<Script
  src={`https://simplecommenter.com/js/comments.min.js?domain=${process.env.NEXT_PUBLIC_SC_DOMAIN}`}
  strategy="afterInteractive"
/>

Conditional Loading

Only load on certain pages:

// app/layout.jsx
import Script from "next/script";
import { headers } from "next/headers";

export default function RootLayout({ children }) {
  const headersList = headers();
  const pathname = headersList.get("x-pathname") || "";

  // Only load on certain paths
  const showWidget = ["/", "/about", "/contact"].some(
    (path) => pathname.startsWith(path)
  );

  return (
    <html lang="en">
      <body>
        {children}
        {showWidget && (
          <Script
            src="https://simplecommenter.com/js/comments.min.js?domain=your-domain.com"
            strategy="afterInteractive"
          />
        )}
      </body>
    </html>
  );
}

For conditional loading, you may need middleware to set the pathname header.

Page-Specific Widget

To only add the widget to specific pages, import Script in that page:

// app/feedback/page.jsx
import Script from "next/script";

export default function FeedbackPage() {
  return (
    <>
      <h1>Feedback</h1>
      <p>Leave us your feedback!</p>
      <Script
        src="https://simplecommenter.com/js/comments.min.js?domain=your-domain.com"
        strategy="afterInteractive"
      />
    </>
  );
}

Verifying Installation

  1. Run your development server (npm run dev)
  2. Open your app in the browser
  3. Look for the feedback widget button
  4. Check browser console (F12) for errors
  5. Test across different routes

Troubleshooting

Widget not appearing

  • Verify the Script component is in your layout/app file
  • Check the domain matches your dashboard settings exactly
  • Ensure no Content Security Policy is blocking the script
  • Try beforeInteractive strategy if afterInteractive doesn't work

Script loading twice

  • Remove any duplicate Script components
  • Don't add the script in both layout and individual pages
  • Check if you have it in both _app.jsx and _document.jsx

Hydration issues

If you see hydration warnings:

  • Move the Script component inside <body>
  • Use afterInteractive instead of beforeInteractive
  • The widget itself doesn't cause hydration issues as it injects into the DOM after load

Static export (next export)

The widget works with static exports. The script loads client-side regardless of how the page is rendered.

Need help? Contact support.

Was this page helpful?