Implement a feature flag system in middleware by reading cookies for persistent assignments, using deterministic logic to assign variants, and using NextResponse.rewrite to serve different page versions without changing the visible URL
Implementing a feature flag system using Next.js middleware allows you to route users to different page variants at the edge, before the page even renders. This approach gives you the power to run A/B tests, roll out features progressively, or show experimental UI to specific user segments—all without rebuilding your application. The core pattern involves: reading or assigning a variant in middleware, storing that decision in a cookie for consistency, and using NextResponse.rewrite() to serve the appropriate page variant while keeping the original URL in the browser address bar .
For more sophisticated needs, the Vercel Flags SDK provides a production-ready foundation. It handles flag definitions, type safety, and integrates with popular providers like LaunchDarkly, Optimizely, and Statsig [citation:9]. The SDK's precompute pattern is particularly powerful for static generation with feature flags—it pre-renders multiple versions of your pages with different flag values, then middleware serves the appropriate version based on the user's assignment [citation:6].
For experiments that involve completely different page structures, you can combine middleware rewrites with separate page files. The Soda SDK [citation:8] demonstrates this pattern elegantly: you define experiments with variant routes, and the SDK automatically assigns users and rewrites to the appropriate path. The user sees /mattress in their browser, but the server serves content from /mattress-a or /mattress-b. This keeps your experiment implementation clean and maintainable.
A critical requirement for feature flags is consistency—users shouldn't flip between variants on each visit. The standard solution is to store assignments in cookies [citation:2]. In the middleware, always check for an existing cookie before assigning a variant. This ensures users have a stable experience and your experiment data remains clean. The cookie should be HttpOnly for security and set with a reasonable expiration (e.g., 30-90 days) to cover the experiment duration [citation:8].
No feature flag system is complete without analytics. When middleware assigns a variant, you should log that decision to your analytics platform. This can be done by setting a cookie that client-side analytics can read, or by calling an analytics API route from the middleware (being careful not to slow down the response) [citation:7]. PostHog, Amplitude, and Segment all provide ways to track experiment assignments and measure conversion differences between variants.
Performance: Middleware must be fast—avoid blocking operations like network requests to external flag services unless absolutely necessary [citation:8].
Cache invalidation: If using a remote flag service, implement caching with appropriate TTL to balance freshness and performance [citation:8].
Fallback behavior: Always have a default variant in case your flag service is unavailable or middleware errors occur [citation:8].
Bot exclusion: Consider excluding known bots from experiments to avoid skewing your data. Check user-agent headers in middleware.
Preview capabilities: Build a way for internal users to force specific variants for testing (e.g., query parameters or admin cookies).
Imagine you need to add a simple A/B test that shows two versions of the homepage based on a feature flag. How would you set up Next.js middleware to read the flag and route the request to the correct page?
If the middleware can't find the flag value in cookies, what fallback behavior would you implement to ensure the user still sees a page?
You added a feature flag middleware that reads flags from an external service, but after deployment some users still see the old page. Walk me through how you'd debug the issue.
Explain the trade‑offs between storing the flag in a cookie versus fetching it on each request in middleware. Which would you choose for a rollout that needs to be toggled quickly, and why?
At scale, fetching flag data from a remote config service on every request can add latency. How would you redesign the middleware to minimize overhead while keeping flags up‑to‑date?
Consider a scenario where you need to serve different page variants to 5% of traffic for a new feature, while ensuring the rest get the stable version. How would you handle consistency and cache invalidation in Next.js middleware and the edge network?
Your organization wants a centralized feature flag platform that works across multiple services, including Next.js front‑ends, Node APIs, and mobile apps. How would you architect the integration so that middleware can reliably route users, and what governance processes would you put in place?
Legacy pages in the app still use getServerSideProps for routing. How would you migrate them to a middleware‑based flag system without causing downtime, and what risks would you monitor during the rollout?