Setting the file. One moment.
Skill 09 · Contentful Personalization
Subchapter 9.11
references/middleware-patterns.mdMarkdown4 KBView on GitHub
Middleware is the most common source of setup failures. Treat matcher and cookie behavior as first-class design decisions.
| Pattern | Use when | Notes |
|---|
| Client-only | Personalized HTML on first response is not required | Simplest operationally |
| Hybrid SSR or edge plus client | Personalized HTML must be correct on first response and a client SDK will hydrate afterward | Recommended default for SSR or edge setups |
| Server-only | No client SDK will run at all | Poor fit for most experimentation and insights use cases |
// middleware.ts (project root)
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const response = NextResponse.next();
// Forward ntaid cookie for personalization continuity
const ntaid = request.cookies.get('ntaid');
if (ntaid) {
response.headers.set('x-ntaid', ntaid.value);
}
return response;
}
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};Recommended flow:
ntaid from the incoming request cookie.POST /profiles?type=preflightPOST /profiles/{ntaid}?type=preflightntaid from response.data.profile.id.Why preflight matters:
Use this only when no client SDK will run after render.
Rules:
The matcher should include all routes that serve personalized content.
Common patterns:
// Broad: all pages except static assets
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)']
// Specific paths
matcher: ['/', '/blog/:path*', '/products/:path*']ntaid from the request.ntaid from response.data.profile.id, never from the old cookie value.Recommended cookie attributes:
Path=/; Max-Age=31536000; SameSite=Lax; SecurecountryCode often causes audience evaluation to reflect the server location instead of the visitor location.middleware.ts placed in wrong directory (must be at project root, not inside app/ or src/)ntaid cookie forwarding breaks profile continuityntaid is updated from the API response profile ID.