Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/snippets/app/.well-known/vercel/flags/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as adapterFlags from '../../../concepts/adapters/flags';
import * as basicIdentifyFlags from '../../../concepts/identify/basic/flags';
import * as fullIdentifyFlags from '../../../concepts/identify/full/flags';
import * as dashboardFlags from '../../../examples/dashboard-pages/flags';
import * as basicEdgeMiddlewareFlags from '../../../examples/feature-flags-in-edge-middleware/flags';
import * as basicProxyFlags from '../../../examples/feature-flags-in-proxy/flags';
// The @/ import is not working in the ".well-known" folder due do the dot in the path.
// We need to use relative paths instead. This seems like a TypeScript issue.
import * as marketingFlags from '../../../examples/marketing-pages/flags';
Expand All @@ -21,7 +21,7 @@ export async function GET(request: NextRequest) {
...dashboardFlags,
...topLevelFlags,
...adapterFlags,
...basicEdgeMiddlewareFlags,
...basicProxyFlags,
...basicIdentifyFlags,
...fullIdentifyFlags,
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { precompute } from 'flags/next';
import { type NextRequest, NextResponse } from 'next/server';
import { marketingFlags } from './flags';

export async function automaticPrecomputeMiddleware(request: NextRequest) {
export async function automaticPrecomputeProxy(request: NextRequest) {
// precompute the flags
const code = await precompute(marketingFlags);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { type NextRequest, NextResponse } from 'next/server';
import { manualPrecomputeFlag } from './flags';

export async function manualPrecomputeMiddleware(request: NextRequest) {
export async function manualPrecomputeProxy(request: NextRequest) {
// use the flag
const value = await manualPrecomputeFlag();

Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { flag } from 'flags/next';

export const basicProxyFlag = flag<boolean>({
key: 'basic-proxy-flag',
decide({ cookies }) {
return cookies.get('basic-proxy-flag')?.value === '1';
},
});
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
'use client';

export function actAsFlaggedInUser() {
document.cookie = 'basic-edge-middleware-flag=1; Path=/';
document.cookie = 'basic-proxy-flag=1; Path=/';
window.location.reload();
}

export function actAsFlaggedOutUser() {
document.cookie = 'basic-edge-middleware-flag=0; Path=/';
document.cookie = 'basic-proxy-flag=0; Path=/';
window.location.reload();
}

export function clear() {
document.cookie =
'basic-edge-middleware-flag=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT';
'basic-proxy-flag=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT';
window.location.reload();
}
11 changes: 11 additions & 0 deletions examples/snippets/app/examples/feature-flags-in-proxy/proxy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { type NextRequest, NextResponse } from 'next/server';
import { basicProxyFlag } from './flags';

export async function featureFlagsInProxy(request: NextRequest) {
const active = await basicProxyFlag();
const variant = active ? 'variant-on' : 'variant-off';

return NextResponse.rewrite(
new URL(`/examples/feature-flags-in-proxy/${variant}`, request.url),
);
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { DemoFlag } from '@/components/demo-flag';
import { Button } from '@/components/ui/button';
import { basicEdgeMiddlewareFlag } from './flags';
import { basicProxyFlag } from './flags';
import { actAsFlaggedInUser, actAsFlaggedOutUser, clear } from './handlers';

// This component does not actually use the feature flag, but the
// variant-on and variant-off pages know about the value statically.
export function Shared({ variant }: { variant: 'on' | 'off' }) {
return (
<>
<DemoFlag name={basicEdgeMiddlewareFlag.key} value={variant === 'on'} />
<DemoFlag name={basicProxyFlag.key} value={variant === 'on'} />
<div className="flex gap-2">
<Button onClick={actAsFlaggedInUser} variant="outline">
Act as a flagged in user
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const getOrGenerateVisitorId = async (
const cookieVisitorId = cookies.get('marketing-visitor-id')?.value;
if (cookieVisitorId) return cookieVisitorId;

// check headers in case middleware set a cookie on the response, as it will
// check headers in case proxy set a cookie on the response, as it will
// not be present on the initial request
const headerVisitorId = headers.get('x-marketing-visitor-id');
if (headerVisitorId) return headerVisitorId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { type NextRequest, NextResponse } from 'next/server';
import { marketingFlags } from './flags';
import { getOrGenerateVisitorId } from './get-or-generate-visitor-id';

export async function marketingMiddleware(request: NextRequest) {
export async function marketingProxy(request: NextRequest) {
// assign a cookie to the visitor
const visitorId = await getOrGenerateVisitorId(
request.cookies,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { precompute } from 'flags/next';
import { type NextRequest, NextResponse } from 'next/server';
import { coreFlags } from './flags';

export async function pprShellsMiddleware(request: NextRequest) {
export async function pprShellsProxy(request: NextRequest) {
// precompute the flags
const code = await precompute(coreFlags);

Expand Down
6 changes: 3 additions & 3 deletions examples/snippets/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ export default function Page() {
href="/examples/marketing-pages"
/>
<ConceptCard
title="Feature Flags in Edge Middleware"
description="Manually using feature flags in Edge Middleware"
href="/examples/feature-flags-in-edge-middleware"
title="Feature Flags in Proxy"
description="Manually using feature flags in Proxy"
href="/examples/feature-flags-in-proxy"
/>
<ConceptCard
title="Pages Router (Basic)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { precompute } from 'flags/next';
import { type NextRequest, NextResponse } from 'next/server';
import { exampleFlags } from './flags';

export async function pagesRouterMiddleware(request: NextRequest) {
export async function pagesRouterProxy(request: NextRequest) {
// precompute the flags
const code = await precompute(exampleFlags);

Expand Down
30 changes: 14 additions & 16 deletions examples/snippets/proxy.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,34 @@
import type { NextRequest } from 'next/server';
import { NextResponse } from 'next/server';
import { automaticPrecomputeMiddleware } from './app/concepts/precompute/automatic/[code]/middleware';
import { manualPrecomputeMiddleware } from './app/concepts/precompute/manual/middleware';
import { featureFlagsInEdgeMiddleware } from './app/examples/feature-flags-in-edge-middleware/middleware';
import { marketingMiddleware } from './app/examples/marketing-pages/middleware';
import { pprShellsMiddleware } from './app/examples/suspense-fallbacks/middleware';
import { pagesRouterMiddleware } from './lib/pages-router-precomputed/middleware';
import { automaticPrecomputeProxy } from './app/concepts/precompute/automatic/[code]/proxy';
import { manualPrecomputeProxy } from './app/concepts/precompute/manual/proxy';
import { featureFlagsInProxy } from './app/examples/feature-flags-in-proxy/proxy';
import { marketingProxy } from './app/examples/marketing-pages/proxy';
import { pprShellsProxy } from './app/examples/suspense-fallbacks/proxy';
import { pagesRouterProxy } from './lib/pages-router-precomputed/proxy';

export function proxy(request: NextRequest) {
if (request.nextUrl.pathname === '/concepts/precompute/manual') {
return manualPrecomputeMiddleware(request);
return manualPrecomputeProxy(request);
}

if (request.nextUrl.pathname === '/concepts/precompute/automatic') {
return automaticPrecomputeMiddleware(request);
return automaticPrecomputeProxy(request);
}

if (request.nextUrl.pathname === '/examples/marketing-pages') {
return marketingMiddleware(request);
return marketingProxy(request);
}

if (
request.nextUrl.pathname === '/examples/feature-flags-in-edge-middleware'
) {
return featureFlagsInEdgeMiddleware(request);
if (request.nextUrl.pathname === '/examples/feature-flags-in-proxy') {
return featureFlagsInProxy(request);
}

if (request.nextUrl.pathname === '/examples/pages-router-precomputed') {
return pagesRouterMiddleware(request);
return pagesRouterProxy(request);
}
if (request.nextUrl.pathname === '/examples/suspense-fallbacks') {
return pprShellsMiddleware(request);
return pprShellsProxy(request);
}

return NextResponse.next();
Expand All @@ -41,7 +39,7 @@ export const config = {
'/concepts/precompute/manual',
'/concepts/precompute/automatic',
'/examples/marketing-pages',
'/examples/feature-flags-in-edge-middleware',
'/examples/feature-flags-in-proxy',
'/examples/pages-router-precomputed',
'/examples/suspense-fallbacks',
],
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-posthog/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const marketingGate = flag<boolean>({

Note: `posthog-node` does not support the Edge Runtime.

To use with middleware and precompute, read more: [Middleware now supports Node.js](https://vercel.com/changelog/middleware-now-supports-node-js)
To use with Routing Middleware and precompute, read more: [Middleware now supports Node.js](https://vercel.com/changelog/middleware-now-supports-node-js)

## Documentation

Expand Down
4 changes: 2 additions & 2 deletions packages/flags/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ The feature flags toolkit for Next.js and SvelteKit.
From the creators of Next.js, the Flags SDK is a free open-source library that gives you the tools you need to use feature flags in Next.js and SvelteKit applications.

- Works with any flag provider, custom setups or no flag provider at all
- Compatible with App Router, Pages Router, and Edge Middleware
- Compatible with App Router, Pages Router, and Routing Middleware
- Built for feature flags and experimentation

See [flags-sdk.dev](https://flags-sdk.dev/) for full docs and examples.
Expand Down Expand Up @@ -62,7 +62,7 @@ export default async function Page() {
}
```

Feature Flags can also be called in Edge Middleware and API Routes.
Feature Flags can also be called in Routing Middleware and API Routes.

## Adapters

Expand Down
2 changes: 1 addition & 1 deletion packages/flags/src/sveltekit/env.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// We're doing this dance so that the flags package is usable both in the SvelteKit environment
// as well as other environments that don't know about '$env/dynamic/private', such as Edge Middleware
// as well as other environments that don't know about '$env/dynamic/private', such as Routing Middleware
let default_secret: string | undefined = process.env.FLAGS_SECRET;

export async function tryGetSecret(secret?: string): Promise<string> {
Expand Down
2 changes: 1 addition & 1 deletion packages/flags/src/sveltekit/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ function getIdentify<ValueType, EntitiesType>(

/**
* Used when a flag is called outside of a request context, i.e. outside of the lifecycle of the `handle` hook.
* This could be the case when the flag is called from edge middleware.
* This could be the case when the flag is called from routing functions.
*/
const requestMap = new WeakMap<Request, AsyncLocalContext>();

Expand Down
2 changes: 1 addition & 1 deletion packages/flags/src/sveltekit/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type FlagsMeta<ReturnValue> = {
type RegularFlag<ReturnValue> = {
(): ReturnValue | Promise<ReturnValue>;
(
/** Only provide this if you're retrieving the flag value outside of the lifecycle of the `handle` hook, e.g. when calling it inside edge middleware. */
/** Only provide this if you're retrieving the flag value outside of the lifecycle of the `handle` hook, e.g. when calling it inside routing functions. */
request?: Request,
secret?: string,
): ReturnValue | Promise<ReturnValue>;
Expand Down
2 changes: 1 addition & 1 deletion tests/next-16/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const config = {
matcher: ['/', '/pages-router', '/app-router-static', '/pages-router-static'],
};

export default async function middleware(request: NextRequest) {
export default async function proxy(request: NextRequest) {
if (
request.nextUrl.pathname === '/' ||
request.nextUrl.pathname === '/pages-router'
Expand Down
Loading