New Relic browser error tracking¶
How it works¶
One New Relic Browser app receives errors from every deployment (production, staging, and preview branches). Each error is tagged with deploy_env and deploy_branch so you can filter by environment or branch. Source maps are generated and uploaded only for production (main), so only production errors get unminified stack traces; staging and previews still report errors but with minified stacks.
1. Who builds what¶
| Builder | When | Source maps? | What happens |
|---|---|---|---|
| Cloudflare | Every push (all branches) | No | Runs npm run build:cloudflare → sets deploy env from CF_PAGES_BRANCH → next build (no maps). Deploys the app. |
| GitHub CI | On push to main (or similar) |
Yes | Sets UPLOAD_SOURCEMAPS=1 and NR secrets → npm run build → generates maps, postbuild uploads them to New Relic and deletes local .map files. Does not deploy. |
Cloudflare never generates or uploads source maps; it only builds and deploys. GitHub CI is the only place that produces and uploads maps, and only for the production build.
2. How deploy_env and deploy_branch get set¶
On Cloudflare, the build command is npm run build:cloudflare. That runs:
scripts/set-build-env.sh
Cloudflare injectsCF_PAGES_BRANCH(e.g.main,staging,feat/xyz) into the build environment. The script reads it and exports:NEXT_PUBLIC_DEPLOY_BRANCH=CF_PAGES_BRANCH(the actual branch name).-
NEXT_PUBLIC_DEPLOY_ENV=productionif branch ismain,stagingif branch isstaging, otherwisepreview. -
npm run build
Next.js bakesNEXT_PUBLIC_*into the client bundle. So every page load has the correct branch and env for that deployment. -
At runtime
When the app loads in the browser,instrumentation-client.tsruns. After the New Relic agent initializes, it callsnewrelic.setCustomAttribute('deploy_env', ...)andsetCustomAttribute('deploy_branch', ...)with those baked-in values. Every subsequent error (and other events) sent to New Relic carry these attributes.
So you don’t configure env per branch in Cloudflare; one build command works for main, staging, and every preview branch.
3. How errors are reported¶
- Unhandled errors:
window.onerrorandwindow.onunhandledrejectionare wired ininstrumentation-client.tsto callreportError, which callsnewrelic.noticeError(error)when the agent is loaded. - Handled errors: You can call
window.ErrorHandler(error)orErrorHandler(error)from anywhere; it reports to New Relic with the same attributes. - All of these events include the current
deploy_envanddeploy_branchset at agent init.
4. How source maps work (production only)¶
- Next.js: In
next.config.ts,productionBrowserSourceMapsistrueonly whenUPLOAD_SOURCEMAPS=1. Cloudflare does not set that, so its builds don’t emit.mapfiles. - GitHub CI: A job (e.g. on push to
main) setsUPLOAD_SOURCEMAPS=1,NR_APPLICATION_ID,NR_API_KEY, andBASE_URL(your production URL), then runsnpm run build. The build generates.mapfiles; the postbuild script uploads each to New Relic (using the productionBASE_URLfor the JS URLs) and then deletes them locally. So only production gets unminified stack traces in New Relic; staging and preview stacks stay minified.
Cloudflare Pages¶
Full setup steps (Story Desk SSG + New Relic + PostHog) are in docs/cloudflare-setup.md.
- Build command:
npm run build:cloudflare
This runsscripts/set-build-env.sh(which setsNEXT_PUBLIC_DEPLOY_BRANCHandNEXT_PUBLIC_DEPLOY_ENVfromCF_PAGES_BRANCH) thennpm run build. No per-branch env configuration needed. - Source maps on Cloudflare (optional): To get source maps for the Cloudflare-built deployment, set
UPLOAD_SOURCEMAPS=1,NR_APPLICATION_ID,NR_API_KEY, andBASE_URL(production origin) in Cloudflare Pages env for the production branch. Then this build generates maps, postbuild uploads them to New Relic and deletes them locally. If you do not set these, Cloudflare builds produce no.mapfiles and the upload script logs "No .js.map files"; only GitHub CI (or another build with these env vars) can upload maps.
GitHub CI (source maps for production only)¶
Run a job on push to main (or after production deploy) that:
- Sets
UPLOAD_SOURCEMAPS=1,NR_APPLICATION_ID,NR_API_KEY(must be a User API key from New Relic, not the license key—otherwise upload returns Unauthorized),BASE_URL=<production URL>(e.g. from secrets). - Runs
npm run build. Postbuild uploads source maps to New Relic and removes local.mapfiles.
Staging and preview branches do not need this job; they report errors with minified stacks but tagged by branch/env.
Filtering errors in New Relic¶
All deployments (main, staging, previews) report to the same Browser app. Use custom attributes:
deploy_env:production(main) |staging|previewdeploy_branch: Git branch name (e.g.main,staging,feat/xyz)
Filter or group by these in the New Relic UI to see errors by environment or branch.