Skip to content

Commit

Permalink
redo landing page
Browse files Browse the repository at this point in the history
  • Loading branch information
dferber90 committed Dec 17, 2024
1 parent 76d6d3c commit ff437da
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 45 deletions.
11 changes: 11 additions & 0 deletions examples/docs/app/getting-started/overview/[code]/flags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { flag } from '@vercel/flags/next';

export const randomFlag = flag<boolean>({
key: 'random-flag',
description: 'A flag that is on for 50% of visitors',
decide() {
return Math.random() > 0.5;
},
});

export const overviewFlags = [randomFlag];
13 changes: 13 additions & 0 deletions examples/docs/app/getting-started/overview/[code]/middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { precompute } from '@vercel/flags/next';
import { type NextRequest, NextResponse } from 'next/server';
import { overviewFlags } from './flags';

export async function overviewMiddleware(request: NextRequest) {
// precompute the flags
const code = await precompute(overviewFlags);

// rewrite the page with the code
return NextResponse.rewrite(
new URL(`/getting-started/overview/${code}`, request.url),
);
}
72 changes: 72 additions & 0 deletions examples/docs/app/getting-started/overview/[code]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Content } from '@/components/content';
import { DemoFlag } from '@/components/demo-flag';
import { randomFlag, overviewFlags } from './flags';
import { ReloadButton } from './reload-button';
import { CodeBlock } from '@/components/code-block';
import Link from 'next/link';

export const dynamic = 'error';

export default async function Page({
params,
}: {
params: Promise<{ code: string }>;
}) {
const awaitedParams = await params;
const overview = await randomFlag(awaitedParams.code, overviewFlags);
return (
<Content crumbs={['getting-started', 'overview']}>
<h3>Overview</h3>
<p>The Flags SDK makes it easy to use feature flags in Next.js.</p>
<ul>
<li>Works with any flag provider, with built-in adapters for many</li>
<li>App Router, Pages Router and Edge Middleware compatible</li>
<li>Supports dynamic and static pages</li>
<li>Implements best practices to avoid common pitfalls</li>
</ul>
<h4>Usage example</h4>
<p>
Declare a new feature flag using the <code>flag</code> function.
</p>
<CodeBlock>
{`
import { flag } from '@vercel/flags/next';
export const randomFlag = flag({
key: "random-flag",
decide() {
// this flag will be on for 50% of visitors
return Math.random() > 0.5;
}
});`}
</CodeBlock>
<p>Use the flag by calling it like any other async function.</p>
<CodeBlock>{`await randomFlag()`}</CodeBlock>
<p>This demo flag is on for 50% of visitors.</p>
<DemoFlag name={randomFlag.key} value={overview} />
<ReloadButton />
<p>
See the <Link href="/getting-started/quickstart">Quickstart</Link> for
full setup instructions.
</p>
<h4>Introduction</h4>
<p>
This package provides a simple way to use feature flags in your Next.js
applications. It can be used no matter if your application is hosted on
Vercel or not. It works with App Router, Pages Router and Edge
Middleware. It also works with any feature flag provider.
</p>
<p>
This package encodes the best practices when using feature flags in
Next.js. We also understand that you sometimes need to deviate from the
golden path, and have examples for those cases as well.
</p>
<p>
While this package is called <code>@vercel/flags</code> it does not
require using Vercel. It is also not limited to feature flags, and can
be used for experimentation, A/B testing and any other dynamic flagging
of code.
</p>
</Content>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use client';

import { Button } from '@/components/ui/button';
import { useRouter } from 'next/navigation';

export function ReloadButton() {
const router = useRouter();

return (
<Button
type="button"
onClick={() => {
router.refresh();
}}
variant="outline"
>
Reload page
</Button>
);
}
2 changes: 2 additions & 0 deletions examples/docs/app/nav-items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@ export const navItems: Item[] = [
title: 'Why Feature Flags?',
slug: 'why-feature-flags',
url: '/philosophy/why-feature-flags',
nav: 'hidden',
},
{
title: 'Why Experimentation?',
slug: 'why-experimentation',
url: '/philosophy/why-experimentation',
nav: 'hidden',
},
{
title: 'Flags as Code',
Expand Down
39 changes: 0 additions & 39 deletions examples/docs/app/page.tsx

This file was deleted.

18 changes: 12 additions & 6 deletions examples/docs/app/philosophy/page.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
import { Content } from '@/components/content';
import Link from 'next/link';

export default function Page() {
return (
<Content crumbs={['philosophy']}>
<h2>Philosophy</h2>
<p>
We believe the best way to use feature flags is to use them server-side.
Using feature flags server-side prevents common problems that come with
client-side usage, like layout shift or flashing the wrong content.
The Flags SDK encodes best practices and opinionated patterns around
flag usage.
</p>
<p>At a glance, the philosophy is:</p>
<ul>
<li>flags are always used server-side</li>
<li>flags do not accept arguments on the call-side</li>
<li>flags declare their evaluation context</li>
<li>flags delcare their default value</li>
</ul>
<p>
This approach fits extremely well with the App Router in Next.js. With
React Server Components, there is always a way to load feature flags on
the server.
Read more about this philosophy in the{' '}
<Link href="/philosophy/flags-as-code">Flags as Code</Link> section.
</p>
</Content>
);
Expand Down
6 changes: 6 additions & 0 deletions examples/docs/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { marketingMiddleware } from './app/examples/marketing-pages/middleware';
import { overviewMiddleware } from './app/getting-started/overview/[code]/middleware';
import { featureFlagsInEdgeMiddleware } from './app/examples/feature-flags-in-edge-middleware/middleware';

export function middleware(request: NextRequest) {
if (request.nextUrl.pathname === '/') {
return overviewMiddleware(request);
}

if (request.nextUrl.pathname === '/examples/marketing-pages') {
return marketingMiddleware(request);
}
Expand All @@ -19,6 +24,7 @@ export function middleware(request: NextRequest) {

export const config = {
matcher: [
'/',
'/examples/marketing-pages',
'/examples/feature-flags-in-edge-middleware',
],
Expand Down

0 comments on commit ff437da

Please sign in to comment.