Cashline

Docs

Next.js

Next.js App Router should load the snippet once in app/layout.tsx. afterInteractive is enough. Do not invent pageviews in getServerSideProps — the browser sends them.

Root layout

Use next/script. Point src at your Cashline origin. The data-site attribute is your site ID.

import Script from "next/script";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en-ZA">
      <body>
        <Script id="cashline-queue" strategy="beforeInteractive">
          {`window.cashline=window.cashline||function(){(window.cashline.q=window.cashline.q||[]).push(arguments)}`}
        </Script>
        <Script
          src="https://YOUR_ORIGIN/cashline.js"
          data-site="cl_your_site_id"
          strategy="afterInteractive"
          onLoad={() => {
            if (typeof window.cashline === "function") window.cashline("pageview");
          }}
        />
        {children}
      </body>
    </html>
  );
}

Purchase after the processor confirms

Amount is rand, not cents. Call this from a client handler after Paystack (or your own webhook) says the charge succeeded. Do not fire it from a Server Component.

"use client";

function onPaid(reference: string) {
  window.cashline?.("purchase", {
    amount: 199,
    currency: "ZAR",
    reference,
  });
}

Client-side goals

After a real signup on the client, fire a goal. Do not fire it from a Server Component.

"use client";

function onSignedUp() {
  window.cashline?.("goal", { name: "signup" });
}