-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add advanced redirects example (#716)
- Loading branch information
1 parent
201da87
commit 0b3f876
Showing
20 changed files
with
2,953 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"root": true, | ||
"extends": "next/core-web-vitals" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# Dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# Testing | ||
/coverage | ||
|
||
# Next.js | ||
/.next/ | ||
/out/ | ||
|
||
# Production | ||
build | ||
dist | ||
|
||
# Misc | ||
.DS_Store | ||
*.pem | ||
|
||
# Debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# Local ENV files | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
# Vercel | ||
.vercel | ||
|
||
# Turborepo | ||
.turbo | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
|
||
next-env.d.ts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"typescript.tsdk": "node_modules/.pnpm/typescript@5.0.2/node_modules/typescript/lib", | ||
"typescript.enablePromptUseWorkspaceTsdk": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# redirect-with-fallback example | ||
|
||
This example shows how to use a [route handler](https://nextjs.org/docs/app/building-your-application/routing/router-handlers) to handle simple redirects. | ||
|
||
The redirects can be found in [`redirects.js`](redirects.js), they are splitted in simple and complex. | ||
|
||
- Simple are handled using a static route ([`generateStaticParams()`](https://nextjs.org/docs/app/api-reference/functions/generate-static-params)) in [`app/[...slug]/route.ts`](app/[...slug]/route.ts) | ||
- Complex are handled via [redirects](https://nextjs.org/docs/app/api-reference/next-config-js/redirects) in [`next.config.js`](next.config.js) | ||
|
||
## Demo | ||
|
||
https://redirect-with-fallback.vercel.app | ||
|
||
## How to Use | ||
|
||
You can choose from one of the following two methods to use this repository: | ||
|
||
### One-Click Deploy | ||
|
||
Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=vercel-examples): | ||
|
||
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/vercel/examples/tree/main/app-directory/redirect-with-fallback&project-name=redirect-with-fallback&repository-name=redirect-with-fallback) | ||
|
||
### Clone and Deploy | ||
|
||
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example: | ||
|
||
```bash | ||
pnpm create next-app --example https://github.com/vercel/examples/tree/main/app-directory/redirect-with-fallback | ||
``` | ||
|
||
Next, run Next.js in development mode: | ||
|
||
```bash | ||
pnpm dev | ||
``` | ||
|
||
Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=edge-middleware-eap) ([Documentation](https://nextjs.org/docs/deployment)). |
48 changes: 48 additions & 0 deletions
48
app-directory/redirect-with-fallback/app/[...slug]/route.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { simpleRedirects } from '../../redirects' | ||
|
||
export const dynamic = 'error' | ||
|
||
interface Params { | ||
slug: string[] | ||
} | ||
|
||
export function GET(_: Request, { params }: { params: Params }): Response { | ||
const sourceFromSlug = params.slug.join('/') | ||
const redirectInfo = simpleRedirects.find( | ||
(r) => normalizeSource(r.source) === sourceFromSlug | ||
) | ||
if (!redirectInfo) { | ||
throw new Error(`Unexpected redirect ${String(params.slug)}`) | ||
} | ||
const status = redirectInfo.statusCode ?? (redirectInfo.permanent ? 308 : 307) | ||
// Response.redirect does not support relative URLs but the `Location` header | ||
// can be used to indicate a redirect to the browser | ||
|
||
return new Response(null, { | ||
status, | ||
headers: { Location: redirectInfo.destination }, | ||
}) | ||
} | ||
|
||
export function generateStaticParams(): Params[] { | ||
const params = simpleRedirects.map((r) => { | ||
return { | ||
slug: normalizeSource(r.source).split('/'), | ||
} | ||
}) | ||
return params | ||
} | ||
|
||
function normalizeSource(source: string): string { | ||
return ( | ||
source | ||
// removes all backslashes | ||
.replace(/\\/g, '') | ||
// removes all leading slashes | ||
.replace(/^\/+/, '') | ||
// Trailing slash syntax. Supported by default for the generated routes. | ||
.replace(/\{\/\}\?$/, '') | ||
// replaces all occurrences of one or more slashes with a single slash | ||
.replace(/\/+/g, '/') | ||
) | ||
} |
17 changes: 17 additions & 0 deletions
17
app-directory/redirect-with-fallback/app/complex-redirect-destination/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { Page, Text, Link, Code, Snippet } from '@vercel/examples-ui' | ||
import { complexRedirects } from '../../redirects' | ||
|
||
export default function Home() { | ||
return ( | ||
<Page className="flex flex-col gap-12"> | ||
<section className="flex flex-col gap-6"> | ||
<Text variant="h1">complex-redirect</Text> | ||
<Text>Config used for this redirect</Text> | ||
<Snippet>{JSON.stringify(complexRedirects[0], null, 2)}</Snippet> | ||
<Text> | ||
<Link href="/">back</Link> | ||
</Text> | ||
</section> | ||
</Page> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import Nav from '@vercel/examples-ui/nav' | ||
import Vercel from '@vercel/examples-ui/icons/vercel' | ||
|
||
import '@vercel/examples-ui/globals.css' | ||
|
||
interface Props { | ||
children: React.ReactNode | ||
} | ||
|
||
export default async function RootLayout({ children }: Props) { | ||
return ( | ||
<html> | ||
<head /> | ||
<body> | ||
<div className="mx-auto h-screen flex flex-col"> | ||
<Nav path="app-directory/redirect-with-fallback" /> | ||
<div className="px-8 bg-accents-0"> | ||
<main>{children}</main> | ||
<footer className="py-10 w-full mt-auto border-t flex items-center justify-center bg-accents-1 z-20"> | ||
<span className="text-primary">Created by</span> | ||
<a | ||
href="https://vercel.com" | ||
aria-label="Vercel.com Link" | ||
target="_blank" | ||
rel="noreferrer" | ||
className="text-black" | ||
> | ||
<Vercel | ||
className="inline-block h-6 ml-3 text-primary" | ||
alt="Vercel.com Logo" | ||
/> | ||
</a> | ||
</footer> | ||
</div> | ||
</div> | ||
</body> | ||
</html> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { Page, Text, Link, Code } from '@vercel/examples-ui' | ||
|
||
export default function Home() { | ||
return ( | ||
<Page className="flex flex-col gap-12"> | ||
<section className="flex flex-col gap-6"> | ||
<Text variant="h1">Redirects</Text> | ||
<ul> | ||
<li> | ||
<Link href="/simple-redirect-source">/simple-redirect-source</Link>{' '} | ||
- handled in a{' '} | ||
<Link href="https://nextjs.org/docs/app/building-your-application/routing/router-handlers"> | ||
Route Handler | ||
</Link> | ||
</li> | ||
<li> | ||
<Link href="/complex-redirect-source"> | ||
/complex-redirect-source | ||
</Link>{' '} | ||
- handled by{' '} | ||
<Link href="https://nextjs.org/docs/app/api-reference/next-config-js/redirects"> | ||
redirects | ||
</Link>{' '} | ||
in <Code>next.config.js</Code> | ||
</li> | ||
</ul> | ||
</section> | ||
</Page> | ||
) | ||
} |
17 changes: 17 additions & 0 deletions
17
app-directory/redirect-with-fallback/app/simple-redirect-destination/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { Page, Text, Link, Code, Snippet } from '@vercel/examples-ui' | ||
import { simpleRedirects } from '../../redirects' | ||
|
||
export default function Home() { | ||
return ( | ||
<Page className="flex flex-col gap-12"> | ||
<section className="flex flex-col gap-6"> | ||
<Text variant="h1">simple-redirect</Text> | ||
<Text>Config used for this redirect</Text> | ||
<Snippet>{JSON.stringify(simpleRedirects[0], null, 2)}</Snippet> | ||
<Text> | ||
<Link href="/">back</Link> | ||
</Text> | ||
</section> | ||
</Page> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
const redirects = require('./redirects').complexRedirects | ||
|
||
/** @type {import('next').NextConfig} */ | ||
module.exports = { | ||
async redirects() { | ||
return redirects | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"name": "redirect-with-fallback", | ||
"repository": "https://github.com/vercel/examples.git", | ||
"license": "MIT", | ||
"private": true, | ||
"scripts": { | ||
"dev": "next dev", | ||
"build": "next build", | ||
"start": "next start", | ||
"lint": "next lint" | ||
}, | ||
"dependencies": { | ||
"@vercel/examples-ui": "^1.0.5", | ||
"next": "latest", | ||
"react": "latest", | ||
"react-dom": "latest" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^18.15.5", | ||
"@types/react": "latest", | ||
"autoprefixer": "^10.4.14", | ||
"eslint": "^8.36.0", | ||
"eslint-config-next": "latest", | ||
"postcss": "^8.4.21", | ||
"tailwindcss": "^3.2.7", | ||
"turbo": "^1.8.5", | ||
"typescript": "^5.0.2" | ||
} | ||
} |
Oops, something went wrong.
0b3f876
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You must have Developer access to commit code to Vercel on Vercel. If you contact an administrator and receive Developer access, commit again to see your changes.
Learn more: https://vercel.com/docs/concepts/teams/roles-and-permissions#enterprise-team-account-roles
0b3f876
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
next-flask – ./python/nextjs-flask
nextjs-python.vercel.app
next-flask-git-main-vercel-labs.vercel.app
next-flask-vercel-labs.vercel.app
nextjs-flask-starter.vercel.app
0b3f876
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
edge-ab-testing-statsig – ./edge-middleware/ab-testing-statsig
edge-ab-testing-statsig.vercel.app
edge-ab-testing-statsig-git-main-now-examples.vercel.app
edge-ab-testing-statsig-now-examples.vercel.app
edge-ab-testing-statsig.vercel.sh
0b3f876
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
redirect-with-fallback – ./app-directory/redirect-with-fallback
redirect-with-fallback-git-main-vercel-solutions-vtest314.vercel.app
redirect-with-fallback.vercel.app
redirect-with-fallback-vercel-solutions-vtest314.vercel.app