Sungtt

[Next.js@13] middleware.ts 미들웨어 사용하기 본문

React

[Next.js@13] middleware.ts 미들웨어 사용하기

sungtt 2022. 12. 21. 16:09

[Next.js@13] middleware.ts 미들웨어 사용하기

버전마다 사용법이 상이하게 달라서 제목에 버전을 명시하기로 했다.

정확히는 13.0.2 환경에서 진행된다.

1. 루트레벨의 폴더에 middleware.ts 파일을 생성한다.

이전에는 각 pages 경로에 middleware파일을 생성하면 그에 맞게 분기되어 실행됐다고한다.

하지만 버셀에서는 고객의 피드백을 받고 이를 단일 파일로 관리할 수 있도록 구조를 변경했다고 한다. 

나는 전역에서 실행되는 미들웨어와, 페이지 구조에 보이는 '/posts/*'에 미들웨어를 설정할 것이다.

2. middelware.ts에 코드를 작성해준다.

공식사이트에선 아래와 같이 req.nextUrl.pathname.startsWith에 접근하여 그에 따른 분기를 나누라고 안내해준다. 앞서 계획대로 전역에서, '/posts/*'에서 실행될 미들웨어 코드를 작성한다.

//middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest, NextFetchEvent } from 'next/server';

export function middleware(req: NextRequest) {

  //전역에서 실행된다.
  console.log('전역 미들웨어 실행');

  // '/posts/*'경로에서 실행된다.
  if (req.nextUrl.pathname.startsWith('/posts')) {
    console.log('게시물을 볼 때 미들웨어');
  }
}

 

3. 작동 확인

사이트에 접속하여 '/posts/*' 경로에서 새로고침 하면 서버에 아래와 같이 콘솔이 출력된다.

위 사진에 전역 미들웨어가 여러번 실행된 이유는 개발자도구의 네트워크탭을 보면 이해할 수 있다.

초기 렌더링 시에 favicon.ico을 가장 먼저 가져오느라 통신하고

그 후 '/posts/3'에 대해 서버사이드렌더링된 html파일을 확인할 수 있다.

아래로도 웹팩, app 파일 등을 가져오는것이 보인다.

 

새로고침이 아닌 페이지 내 정상적인 경로를 통해 이동하게 된다면 아래와 같이 실행된다.

첫번째로 '/posts/*'에 대한 미들웨어가 실행되고

두번째로 전역 미들웨어가 실행되는것을 알 수 있다.

 

4. request에 들어있는 정보

안에 내용을 확인해보면 쿠키, 경로, 헤더 등 여러가지가 들어있다.

{
  cookies: RequestCookies {},
  geo: {},
  ip: undefined,
  nextUrl: {
  href: 'http://localhost:3000/posts/3?idx=3',
  origin: 'http://localhost:3000',
  protocol: 'http:',
  username: '',
  password: '',
  host: 'localhost:3000',
  hostname: 'localhost',
  port: '3000',
  pathname: '/posts/3',
  search: '?idx=3',
  searchParams: URLSearchParams {  },
  hash: ''
},
  url: 'http://localhost:3000/posts/3?idx=3',
  bodyUsed: false,
  cache: 'default',
  credentials: 'same-origin',
  destination: '',
  headers: {
  accept: '*/*',
  accept-encoding: 'gzip, deflate, br',
  accept-language: 'ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7',
  connection: 'keep-alive',
  cookie: '',
  host: 'localhost:3000',
  referer: 'http://localhost:3000/home/title',
  sec-ch-ua: '"Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108"',      
  sec-ch-ua-mobile: '?0',
  sec-ch-ua-platform: '"Windows"',
  sec-fetch-dest: 'empty',
  sec-fetch-mode: 'cors',
  sec-fetch-site: 'same-origin',
  user-agent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36',
  x-nextjs-data: '1'
},
  integrity: '',
  keepalive: false,
  method: 'GET',
  mode: 'cors',
  redirect: 'follow',
  referrer: 'about:client',
  referrerPolicy: '',
  signal: AbortSignal {
  [Symbol(kAborted)]: false,
  [Symbol(kReason)]: undefined,
  [Symbol(kOnabort)]: undefined,
  [Symbol(realm)]: { settingsObject: { baseUrl: undefined } }
}
}

 

 

 

- 참고 사이트

미들웨어

https://nextjs.org/docs/advanced-features/middleware

 

Advanced Features: Middleware | Next.js

Learn how to use Middleware to run code before a request is completed.

nextjs.org

중첩 미들웨어

https://nextjs.org/docs/messages/nested-middleware

 

nested-middleware | Next.js

Nested Middleware You are defining a Middleware file in a location different from /middleware , which is not allowed. While in beta, a Middleware file under specific pages would only be executed when pages below its declaration were matched, allowing nesti

nextjs.org

 

Comments