Add the script to a Next.js shop
This guide is for the Next.js App Router. It covers the browser side: the script, consent and commerce calls from client components.
1. Load the script in the root layout
Section titled “1. Load the script in the root layout”Add two next/script tags to app/layout.tsx:
import Script from "next/script";
export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> <body> {children} <Script id="quomerce-stub" strategy="beforeInteractive"> {`window.qm=window.qm||function(){(window.qm.q=window.qm.q||[]).push(arguments)};qm("init",{key:"pk_live_…",commerce:"manual"});`} </Script> <Script src="https://ingest-prod.quomerce.com/sdk/v0/qm.js" strategy="afterInteractive" /> </body> </html> );}- The stub defines
window.qmas a queue before any of your code runs. A call from a client component that renders before the script has loaded is kept, and run once it has.beforeInteractiveonly works in the root layout, which is where this belongs. - The script loads after the page is interactive and never blocks rendering.
- One copy. Put this in the root layout only. A nested layout that renders it again would load the script twice.
- The key can be inline, as above, or read from an environment variable such as
NEXT_PUBLIC_QM_KEY. It is public either way. commerce: "manual"means this shop sends its own commerce events, as in step 4. Leave it out to useautomode: Quomerce then detects events from your GA4dataLayerand ignores everyqm.commercecall. See Commerce: auto or manual.
Page views need nothing more. App Router navigations change the URL through the History API, and the script counts each one as a page view. New deploys are recognised from the Next.js build ID.
2. Add the types
Section titled “2. Add the types”Download the types file into your project:
curl -o types/qm.d.ts https://docs.quomerce.com/sdk/qm.d.tsNow window.qm is typed everywhere: commands, commerce calls and their arguments. Typos and wrong shapes fail the build. See TypeScript types for details.
3. Pass on consent
Section titled “3. Pass on consent”With the default consent mode (Required), the script stores nothing on the device and records no replay until it is told the visitor agreed. Pass the choice on every page load:
"use client";
import { useEffect } from "react";
export function ConsentBridge() { useEffect(() => { // Cookiebot shown here; any consent tool with a callback works the same way. const apply = () => { const statistics = Boolean(window.Cookiebot?.consent?.statistics); window.qm?.("consent", { analytics: statistics, replay: statistics }); }; window.addEventListener("CookiebotOnConsentReady", apply); return () => window.removeEventListener("CookiebotOnConsentReady", apply); }, []); return null;}
declare global { interface Window { Cookiebot?: { consent?: { statistics?: boolean } }; }}Render <ConsentBridge /> once, in the root layout. More in Consent.
4. Send commerce events
Section titled “4. Send commerce events”In manual mode, call qm.commerce from client components when something happens:
"use client";
import { useEffect } from "react";import type { Product } from "@/types/qm";
export function AddToCart({ product }: { product: Product }) { useEffect(() => { window.qm?.("commerce.productViewed", product); }, [product]);
return ( <button onClick={() => { // …add to the cart, then: window.qm?.("commerce.cartAdded", product, 1); }} > Add to cart </button> );}Use the queued form, window.qm?.("commerce.cartAdded", …). It works before the script has loaded, and the ?. keeps server rendering safe. The full list of calls is in Manual mode.
5. Mark pages and products
Section titled “5. Mark pages and products”-
Product pages are recognised from JSON-LD
Productdata. Render it on the server. It also fills the Products report with each product’s name, price and availability. -
Pages whose URL says nothing, such as an order confirmation at
/order/12345, should say what they are:useEffect(() => {window.qm?.("page", { type: "thank_you" });}, []);This matters for privacy too: checkout, thank-you and account pages are fully masked in replays. See Page types.
6. Check that it works
Section titled “6. Check that it works”Open your shop, accept the consent banner, view a product, add it to the cart and start checkout. Then watch Install & setup. See Check that it works.