Convert middleware-matcher example to TypeScript (#42520)

Converted example to TypeScript to match Contribution docs.
- Set cookies using `NextResponse` instead of the `Set-Cookie` header

## Documentation / Examples

- [X] Make sure the linting passes by running `pnpm build && pnpm lint`
- [X] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
This commit is contained in:
Max Proske 2022-11-05 23:08:06 -07:00 committed by GitHub
parent 257835569c
commit 6290689281
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 60 additions and 32 deletions

View file

@ -2,9 +2,9 @@
This example shows how to configure your [Next.js Middleware](https://nextjs.org/docs/advanced-features/middleware) to only match specific pages.
The index page ([`pages/index.js`](pages/index.js)) has a list of links to dynamic pages, which will tell whether they were matched or not.
The index page ([`pages/index.ts`](pages/index.ts)) has a list of links to dynamic pages, which will tell whether they were matched or not.
The Middleware file ([`middleware.js`](middleware.js)) has a special `matcher` configuration key, allowing you to fine-grained control [matched pages](https://nextjs.org/docs/advanced-features/middleware#matcher).
The Middleware file ([`middleware.ts`](middleware.ts)) has a special `matcher` configuration key, allowing you to fine-grained control [matched pages](https://nextjs.org/docs/advanced-features/middleware#matcher).
Please keep in mind that:

View file

@ -1,18 +0,0 @@
import { NextResponse } from 'next/server'
export default function middleware(req) {
const { pathname } = new URL(req.url)
const response = NextResponse.next()
response.headers.set(
'set-cookie',
`middleware-slug=${pathname.slice(1)}; Path=${pathname}`
)
return response
}
export const config = {
matcher: [
'/disclaimer', // match a single, specific page
'/((?!public|static).*)', // match all paths not starting with 'public' or 'static'
],
}

View file

@ -0,0 +1,24 @@
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export default function middleware(req: NextRequest) {
const path = req.nextUrl.pathname
const slug = path.slice(1)
// Set a cookie on the response using the `ResponseCookies` API
const response = NextResponse.next()
response.cookies.set({
name: 'middleware-slug',
value: slug,
path,
})
return response
}
export const config = {
matcher: [
'/disclaimer', // match a single, specific page
'/((?!public|static).*)', // match all paths not starting with 'public' or 'static'
],
}

View file

@ -7,7 +7,13 @@
},
"dependencies": {
"next": "latest",
"react": "latest",
"react-dom": "latest"
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/node": "^18.11.9",
"@types/react": "^18.0.25",
"@types/react-dom": "^18.0.8",
"typescript": "^4.8.4"
}
}

View file

@ -1,6 +1,6 @@
import { useRouter } from 'next/router'
function hasMiddlewareMatched(slug) {
function hasMiddlewareMatched(slug?: string[]) {
const values =
(typeof document !== 'undefined' ? document.cookie : '')
.split(';')
@ -10,10 +10,10 @@ function hasMiddlewareMatched(slug) {
return values.some((value) => value === slug?.join('/'))
}
export const ContentPage = (props) => {
const {
query: { slug }, // slug is an array of path segments
} = useRouter()
export default function ContentPage() {
const router = useRouter()
const slug = router.query.slug as string[] // slug is an array of path segments
return (
<>
<h1>
@ -25,5 +25,3 @@ export const ContentPage = (props) => {
</>
)
}
export default ContentPage

View file

@ -1,4 +1,4 @@
const Home = () => {
export default function Home() {
const matching = ['/about', '/about/topic/cats', '/public/disclaimer']
const notMatching = ['/public', '/public/disclaimer/nested', '/static']
return (
@ -26,5 +26,3 @@ const Home = () => {
</div>
)
}
export default Home

View file

@ -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"]
}