Skip to content

Commit

Permalink
feat(examples): adds middleware example (#38240)
Browse files Browse the repository at this point in the history
## Documentation / Examples

- [X] Make sure the linting passes by running `pnpm lint`
- [X] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples)


Co-authored-by: Lee Robinson <9113740+leerob@users.noreply.github.com>
  • Loading branch information
edusig and leerob committed Jul 4, 2022
1 parent beaa4df commit 7664a40
Show file tree
Hide file tree
Showing 17 changed files with 206 additions and 0 deletions.
3 changes: 3 additions & 0 deletions examples/middleware/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
35 changes: 35 additions & 0 deletions examples/middleware/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# 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

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
27 changes: 27 additions & 0 deletions examples/middleware/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Middleware

This example shows how to use [Middleware in Next.js](https://nextjs.org/docs/advanced-features/middleware) to run code before a request is completed.

The index page ([`pages/index.tsx`](pages/index.js)) has a list of links to pages with `redirect`, `rewrite`, or normal behavior.

On the Middleware file ([`middleware.ts`](middleware.ts)) the routes are already being filtered by defining a `matcher` on the exported config. If you want the Middleware to run for every request, you can remove the `matcher`.

## Deploy your own

Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/middleware&project-name=middleware&repository-name=middleware)

## How to use

Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example:

```bash
npx create-next-app --example middleware middleware-app
# or
yarn create next-app --example middleware middleware-app
# or
pnpm create next-app --example middleware middleware-app
```

Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
15 changes: 15 additions & 0 deletions examples/middleware/middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { NextRequest, NextResponse } from 'next/server'

export function middleware(request: NextRequest) {
if (request.nextUrl.pathname === '/about') {
return NextResponse.redirect(new URL('/redirected', request.url))
}
if (request.nextUrl.pathname === '/another') {
return NextResponse.rewrite(new URL('/rewrite', request.url))
}
return NextResponse.next()
}

export const config = {
matcher: ['/about/:path*', '/another/:path*'],
}
5 changes: 5 additions & 0 deletions examples/middleware/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
6 changes: 6 additions & 0 deletions examples/middleware/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
}

module.exports = nextConfig
22 changes: 22 additions & 0 deletions examples/middleware/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "latest",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@types/node": "18.0.0",
"@types/react": "18.0.14",
"@types/react-dom": "18.0.5",
"eslint": "8.18.0",
"eslint-config-next": "12.2.0",
"typescript": "4.7.4"
}
}
7 changes: 7 additions & 0 deletions examples/middleware/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { AppProps } from 'next/app'

function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}

export default MyApp
7 changes: 7 additions & 0 deletions examples/middleware/pages/about.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { NextPage } from 'next'

export const AboutPage: NextPage = () => {
return <h1>About</h1>
}

export default AboutPage
7 changes: 7 additions & 0 deletions examples/middleware/pages/about2.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { NextPage } from 'next'

export const About2Page: NextPage = () => {
return <h1>About 2</h1>
}

export default About2Page
7 changes: 7 additions & 0 deletions examples/middleware/pages/another.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { NextPage } from 'next'

export const AnotherPage: NextPage = () => {
return <h1>Another</h1>
}

export default AnotherPage
27 changes: 27 additions & 0 deletions examples/middleware/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { NextPage } from 'next'
import Link from 'next/link'

const Home: NextPage = () => {
return (
<div>
<h1>Index</h1>
<p>
<Link href="/about" passHref>
<a>Go to about page (will redirect)</a>
</Link>
</p>
<p>
<Link href="/another" passHref>
<a>Go to another page (will rewrite)</a>
</Link>
</p>
<p>
<Link href="/about2" passHref>
<a>Go to about 2 page (no redirect or rewrite)</a>
</Link>
</p>
</div>
)
}

export default Home
7 changes: 7 additions & 0 deletions examples/middleware/pages/redirected.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { NextPage } from 'next'

export const RedirectedPage: NextPage = () => {
return <h1>Redirected from /about</h1>
}

export default RedirectedPage
7 changes: 7 additions & 0 deletions examples/middleware/pages/rewrite.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { NextPage } from 'next'

export const RewritePage: NextPage = () => {
return <h1>Rewrite</h1>
}

export default RewritePage
Binary file added examples/middleware/public/favicon.ico
Binary file not shown.
4 changes: 4 additions & 0 deletions examples/middleware/public/vercel.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions examples/middleware/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}

0 comments on commit 7664a40

Please sign in to comment.