Skip to main content

How to add Pulse NPS widget to your react application?

Step by step guide to integrate NPS widget in your react based application

Updated over 2 months ago

If your application is built on Reactjs or Nextjs, here is a quick step by step guide to integrate Pulse NPS widget:

Step 1. Put the loader in a shared utility file

You can create something like src/util/pulseNps.ts

type PulseCustomAttrs = Record<string, unknown>;

export function loadPulseNPS({
userId,
userEmail,
userName,
customAttributes,
}: {
userId: string;
userEmail?: string;
userName?: string;
customAttributes?: PulseCustomAttrs;
}) {
// Prevent duplicate injection
if (document.getElementById("pulse-nps-script")) return;

(window as any).pulseNPSConfig = {
surveyId: "219a8897-8024-431e-bb02-fa9d51c7afd1",
userId,
userEmail,
userName: userName ?? "",
...(customAttributes ?? {}),
};

const script = document.createElement("script");
script.src = "https://api.marmeto.org/pulse/scripts/nps-embed.js";
script.defer = true;
script.id = "pulse-nps-script";

document.body.appendChild(script);
}

2. Call it from the dashboard layout only when data is ready

Your current useEffect will run even when userInfo.id is empty (""). Don’t load the script until you actually have a real userId.

import { useEffect, useMemo } from "react";
import { loadPulseNPS } from "@/lib/pulseNps";

export function DashboardLayout({ userInfo, organizationData }: any) {
const npsAttrs = useMemo(
() => ({
organizationId: organizationData?.id ?? "",
organizationName: organizationData?.name ?? "",
}),
[organizationData?.id, organizationData?.name]
);

useEffect(() => {
const userId = userInfo?.id;
if (!userId) return; // Block until real userId exists

loadPulseNPS({
userId,
userEmail: userInfo?.email ?? "",
userName: userInfo?.name ?? "",
customAttributes: npsAttrs,
});
}, [userInfo?.id, userInfo?.email, userInfo?.name, npsAttrs]);

return <div>{/* ... */}</div>;
}

3. Make it SSR-safe (Next.js / Remix)

If you’re in an SSR environment, this must only run on the client:

if (typeof window === "undefined") return;

Put that at the top of loadPulseNPS().

4. Handle updates when org/user changes

Right now your loader blocks duplicate injection, but if the user switches org (or logs out/in) you may want config to update even if the script is already there.

A simple approach to achieve this:

  • Always update window.pulseNPSConfig

  • Only inject script once

export function loadPulseNPS(...) {   
if (typeof window === "undefined") return;

(window as any).pulseNPSConfig = { ... };

const existing = document.getElementById("pulse-nps-script");
if (existing) return; // script already loaded, config updated

// else inject script...
}

If the embed script reads config only on initial load, you might also need a “re-init” method like:
window.pulseNPS?.init?.() - only if their script exposes it.

5. Debug checklist (To help you quickly verify all you just did)

  • Open DevTools → Network → ensure nps-embed.js loads once.

  • On console: check window.pulseNPSConfig is set before the script loads. If it’s not showing, confirm your effect runs after userInfo is populated (auth hydration timing).


Still have any questions? Talk to us via live chat on your dashboard

Did this answer your question?