---
id: 08-app-wiring-web-next
epic: security-headers-rate-limit-sbom
title: "App wiring: web-next"
type: technical-story
status: done
feature: web-next
depends-on: [07-security-header-adapters]
blocks: []
created: 2026-05-20T00:00:00Z
updated: 2026-05-20T10:14:20.860Z
---

## Goal

Wire the security headers middleware end-to-end in `apps/web-next` — middleware chain, nonce-aware Sentry browser SDK init, and nonce threaded into the document head — producing a Next.js app that emits all six headers with per-request CSP nonces and no CSP violations in the browser console.

## Why

`apps/web-next` is the primary template app; getting it wired first validates the Next.js adapter in a real app context, including the Sentry nonce contract and the `<Script nonce={nonce}>` threading pattern that consumers will copy. The Sentry init integration is non-trivial enough (ADR-014 nonce contract, `replayIntegration` + `feedbackIntegration` both need the nonce) that it justifies its own story to get right before the parallel web-tanstack story begins.

## Done when

- `apps/web-next/middleware.ts` invokes the `core-shared/security/next` middleware and chains it with existing auth checks (security headers apply before auth redirects).
- `apps/web-next/instrumentation-client.ts` reads nonce via `getNonce()` and passes it to `Sentry.init({ integrations: [replayIntegration({ nonce }), feedbackIntegration({ nonce })] })`.
- `apps/web-next/app/layout.tsx` threads nonce from `getNonce()` into `<Script nonce={nonce}>` for any inline scripts in the document head.
- Middleware test asserts: all six headers present in response, CSP shape matches prod template for `NODE_ENV=production`, CSP shape is permissive for `NODE_ENV=development`, `x-nonce` header present.
- No CSP violations appear in browser console when running `pnpm dev` against `localhost:3000`.
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` all pass.

## In scope

- `apps/web-next/middleware.ts` — security headers middleware chained with existing auth middleware.
- `apps/web-next/instrumentation-client.ts` — nonce-aware `Sentry.init`.
- `apps/web-next/app/layout.tsx` — nonce threaded into `<Script>` tags.
- Middleware test: six headers + CSP shape per mode + `x-nonce` presence.

## Out of scope

- TanStack Start and CMS wiring — Story 09.
- CSP report-uri collector — deferred.
- Storybook CSP — explicitly out of Epic C scope.
- HSTS preload list submission — consumer/legal action.

## Tasks

- [x] Wire `core-shared/security/next` middleware in `apps/web-next/middleware.ts` chained before existing auth checks; update `apps/web-next/instrumentation-client.ts` to read nonce via `getNonce()` and pass to `Sentry.init` replay + feedback integrations; thread nonce from `getNonce()` into `<Script nonce={nonce}>` in `apps/web-next/app/layout.tsx`; add middleware test asserting all six headers, prod/dev CSP shape, and `x-nonce` present in response; all gates pass.
