Przejdź do głównej zawartości

Add the script to a Next.js shop

Ta treść nie jest jeszcze dostępna w Twoim języku.

This guide is for the Next.js App Router.

Add two next/script tags to app/layout.tsx:

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 queues calls made before the script loads. Keep it in the root layout only.
  • The key can be inline or read from an environment variable such as NEXT_PUBLIC_QM_KEY. It is public either way.
  • commerce: "manual" means you send commerce events yourself, as in step 4. Leave it out for auto mode, which ignores every qm.commerce call. See Commerce: auto or manual.

Page views, including client-side navigations, need nothing more.

Download the types file into your project:

Terminal window
curl -o types/qm.d.ts https://docs.quomerce.com/sdk/qm.d.ts

Now window.qm is typed, and typos fail the build. See TypeScript types.

With the default consent mode (Required), pass the visitor’s choice on every page load:

app/consent-bridge.tsx
"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.

In manual mode, call qm.commerce from client components:

app/p/[slug]/add-to-cart.tsx
"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 call form, window.qm?.("commerce.cartAdded", …): it works before the script loads, and ?. keeps server rendering safe. All calls are in Manual mode.

  • Product pages are recognised from JSON-LD Product data. Render it on the server.

  • Pages whose URL says nothing, such as an order confirmation at /order/12345, should set their type:

    useEffect(() => {
    window.qm?.("page", { type: "thank_you" });
    }, []);

    Checkout, thank-you and account pages are fully masked in replays. See Page types.

See Check that it works.