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.pulseNPSConfigOnly 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.jsloads once.On console: check
window.pulseNPSConfigis 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