diff --git a/examples/middleware/.eslintrc.json b/examples/middleware/.eslintrc.json new file mode 100755 index 0000000000000..bffb357a71225 --- /dev/null +++ b/examples/middleware/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/examples/middleware/.gitignore b/examples/middleware/.gitignore new file mode 100755 index 0000000000000..737d87210923e --- /dev/null +++ b/examples/middleware/.gitignore @@ -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 diff --git a/examples/middleware/README.md b/examples/middleware/README.md new file mode 100755 index 0000000000000..3f502335dba2c --- /dev/null +++ b/examples/middleware/README.md @@ -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)). diff --git a/examples/middleware/middleware.ts b/examples/middleware/middleware.ts new file mode 100644 index 0000000000000..56e29051ed97d --- /dev/null +++ b/examples/middleware/middleware.ts @@ -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*'], +} diff --git a/examples/middleware/next-env.d.ts b/examples/middleware/next-env.d.ts new file mode 100755 index 0000000000000..4f11a03dc6cc3 --- /dev/null +++ b/examples/middleware/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/examples/middleware/next.config.js b/examples/middleware/next.config.js new file mode 100755 index 0000000000000..a843cbee09afa --- /dev/null +++ b/examples/middleware/next.config.js @@ -0,0 +1,6 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + reactStrictMode: true, +} + +module.exports = nextConfig diff --git a/examples/middleware/package.json b/examples/middleware/package.json new file mode 100644 index 0000000000000..eadc258a1a8db --- /dev/null +++ b/examples/middleware/package.json @@ -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" + } +} diff --git a/examples/middleware/pages/_app.tsx b/examples/middleware/pages/_app.tsx new file mode 100755 index 0000000000000..762941b054807 --- /dev/null +++ b/examples/middleware/pages/_app.tsx @@ -0,0 +1,7 @@ +import type { AppProps } from 'next/app' + +function MyApp({ Component, pageProps }: AppProps) { + return +} + +export default MyApp diff --git a/examples/middleware/pages/about.tsx b/examples/middleware/pages/about.tsx new file mode 100644 index 0000000000000..2b0e0844d5f3f --- /dev/null +++ b/examples/middleware/pages/about.tsx @@ -0,0 +1,7 @@ +import { NextPage } from 'next' + +export const AboutPage: NextPage = () => { + return

About

+} + +export default AboutPage diff --git a/examples/middleware/pages/about2.tsx b/examples/middleware/pages/about2.tsx new file mode 100644 index 0000000000000..7ce3d4fdf69c5 --- /dev/null +++ b/examples/middleware/pages/about2.tsx @@ -0,0 +1,7 @@ +import { NextPage } from 'next' + +export const About2Page: NextPage = () => { + return

About 2

+} + +export default About2Page diff --git a/examples/middleware/pages/another.tsx b/examples/middleware/pages/another.tsx new file mode 100644 index 0000000000000..c0db3a59de6a6 --- /dev/null +++ b/examples/middleware/pages/another.tsx @@ -0,0 +1,7 @@ +import { NextPage } from 'next' + +export const AnotherPage: NextPage = () => { + return

Another

+} + +export default AnotherPage diff --git a/examples/middleware/pages/index.tsx b/examples/middleware/pages/index.tsx new file mode 100755 index 0000000000000..c20dee303c3dc --- /dev/null +++ b/examples/middleware/pages/index.tsx @@ -0,0 +1,27 @@ +import type { NextPage } from 'next' +import Link from 'next/link' + +const Home: NextPage = () => { + return ( +
+

Index

+

+ + Go to about page (will redirect) + +

+

+ + Go to another page (will rewrite) + +

+

+ + Go to about 2 page (no redirect or rewrite) + +

+
+ ) +} + +export default Home diff --git a/examples/middleware/pages/redirected.tsx b/examples/middleware/pages/redirected.tsx new file mode 100644 index 0000000000000..b67db8b5f9732 --- /dev/null +++ b/examples/middleware/pages/redirected.tsx @@ -0,0 +1,7 @@ +import { NextPage } from 'next' + +export const RedirectedPage: NextPage = () => { + return

Redirected from /about

+} + +export default RedirectedPage diff --git a/examples/middleware/pages/rewrite.tsx b/examples/middleware/pages/rewrite.tsx new file mode 100644 index 0000000000000..038c47219ab2a --- /dev/null +++ b/examples/middleware/pages/rewrite.tsx @@ -0,0 +1,7 @@ +import { NextPage } from 'next' + +export const RewritePage: NextPage = () => { + return

Rewrite

+} + +export default RewritePage diff --git a/examples/middleware/public/favicon.ico b/examples/middleware/public/favicon.ico new file mode 100755 index 0000000000000..718d6fea4835e Binary files /dev/null and b/examples/middleware/public/favicon.ico differ diff --git a/examples/middleware/public/vercel.svg b/examples/middleware/public/vercel.svg new file mode 100755 index 0000000000000..fbf0e25a651c2 --- /dev/null +++ b/examples/middleware/public/vercel.svg @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/examples/middleware/tsconfig.json b/examples/middleware/tsconfig.json new file mode 100755 index 0000000000000..99710e857874f --- /dev/null +++ b/examples/middleware/tsconfig.json @@ -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"] +}