Skip to content

Embed on Next.js

Add a HappySaid testimonial widget to a Next.js app with the Script component in a client component, why it mounts in onReady, and what your CSP needs to allow.

On this page

In a Next.js app, use the built-in Script component and mount the widget when it has loaded.

Create a component

Add this as a client component. The "use client" line is needed because onReady is a function, and a Server Component can't pass one.

tsx
"use client";
import Script from "next/script";

declare global {
  interface Window {
    HappySaid?: { mount(): void };
  }
}

export function Testimonials() {
  return (
    <>
      <div data-happysaid="YOUR_WIDGET_ID" style={{ minHeight: 480 }} />
      <Script
        src="https://cdn.happysaid.com/w.js"
        strategy="lazyOnload"
        onReady={() => window.HappySaid?.mount()}
      />
    </>
  );
}

Replace YOUR_WIDGET_ID with the ID from Get code in HappySaid. The Next.js tab has the same code with your ID filled in.

Use it

Import the component into any page or layout and render it where you want the widget. Because it's a client component, you can import it from a Server Component without further changes.

Why onReady

onReady runs when the script has loaded, and also when the component mounts again after a client-side navigation. Calling mount() makes the widget draw into the new element. A widget already drawn isn't drawn twice.

Content security policy

If you set a content security policy, allow cdn.happysaid.com in script-src, your HappySaid API address in connect-src, and https: in img-src. If you can't, use the iframe.

If nothing shows

  1. Check the widget has at least one approved testimonial.
  2. Check the browser console for blocked requests.
  3. Make sure the div is rendered on the page you're viewing.

Still stuck? Email support@happysaid.com