# Next.js and custom apps

Track actions in your app only after they really succeed.



## What you need [#what-you-need]

You need access to edit the app and backend, plus an approved tracking plan prepared for testing. The server code needs Tyton’s private `@tyton/sdk` build; `npm install tyton` does not provide it.

## Install at the success boundary [#install-at-the-success-boundary]

1. Initialize the browser runtime once on the client, with `consent: "wait"` and `mode: "verify"`. Use either the [script or browser SDK](/docs/tracking/sdk-and-browser). Do not initialize it while rendering on the server.
2. Initialize `@tyton/sdk/server` inside server-only code. Store `TYTON_SECRET_KEY` in private environment configuration. Never prefix it with `NEXT_PUBLIC_`: Next.js exposes those variables in browser bundles. See [Next.js environment variables](https://nextjs.org/docs/app/guides/environment-variables).
3. After your backend confirms the action succeeded, wait for the approved conversion call to finish. In a Next.js App Router app, this may belong in a [Route Handler](https://nextjs.org/docs/app/api-reference/file-conventions/route). Check payment-provider notifications before calling a payment successful.

For example, your lead endpoint validates the form, commits a submission, and returns its ID. Only then can the browser record the approved Lead using that same ID. A thrown validation error never reaches the success callback.

## Success check [#success-check]

Test a successful action, invalid input, a backend error, and a repeated request. Browser and server copies of one action need the same ID. Retrying tracking must not create another order or lead, and tracking failure must not undo a successful business action.

## If you get stuck [#if-you-get-stuck]

A static export has no backend that runs when someone makes a request. Put server tracking in your real backend, never in browser code. In a single-page app, check whether another tracker creates duplicate PageViews on navigation; Tyton’s live runtime already watches path changes. Local HTTP tests can help, but the reviewed conversion must match the real HTTPS site and path.
