next.js의 rewrite와 redirect

dana·2023년 1월 17일
14

Next.js

목록 보기
6/13
post-thumbnail

tldr; 유저가 어떤 path로 접근하는 경우, 특정 사이트로 옮겨주는 next 자체 기능 2가지
공식 문서 확인하기 : rewrites / redirect

공통점과 차이점

공통점

next.js에서는 rewriteredirect 기능을 제공한다.
두가지 모두 유저가 특정 path로 이동시 정해진 화면이 보이도록 한다.

차이점

두 설정의 다른 점은
rewrite는 유저가 입력한 url 그대로 유저에게 보여져 유저는 화면이 변경된지 모르는 반면,
redirect는 정해진 path로 url이 바뀌게 된다.

예를 들어 유저가 www.minju.com/old 라는 path로 진입시, www.minju.com/new의 페이지를 보여주고 싶다면,
rewrite는 주소창의 url이 www.minju.com/old 인채로 /new의 화면이 보여지고
redirectwww.minju.com/oldwww.minju.com/new로 리다이렉트 해주어 유저가 입력한 값과 달리 www.minju.com/new가 주소창에 나타나게 된다.

설정 방법

설정 방법은 next.config.js 파일에 다음과 같은 설정값을 추가해주면 된다.

module.exports = {
  // rewrite
  async rewrites() {
    return [
      {
        // source : 유저가 진입할 path
        // destination : 유저가 이동할 path
        source: '/about',
        destination: '/',
      },
    ]
  },
  // redirect
  async redirects() {
    return [
      {
        source: '/about',
        destination: '/',
        permanent: true,
      },
    ]
  },
}

permanent 속성에 대해선 아래 속성에서 함께 소개하도록 하겠다.

source와 destination

path 매칭

:path

: 를 이용해 다이나믹한 path 값을 받아올 수 있다.

source: '/old-blog/:slug',
destination: '/news/:slug',

이렇게 설정되어있는 경우,
/old-blog/apple 입력시 /news/apple
/old-blog/banana 입력시 /news/banana로 이동된다.

만약 /old-blog/apple/green으로 입력시, 일치하는 경로가 없어 입력한 url(🍏) 그대로 이동된다.

:path*

하지만 다이나믹 path 옆에 *을 붙인다면?

source: '/old-blog/:slug*',
destination: '/news/:slug*',

/old-blog/apple/green -> /news/apple/green
/old-blog/apple/green/delicious -> /news/apple/green/delicious
경로 길이에 상관 없이 rewrite 혹은 redirect 된다.

와일드 카드 / 정규식

도 사용 가능하다^ㅁ^

rewrite에서만 적용되는 자동 쿼리

rewrite에서는 생략된 path에 대해 자동 쿼리로 넘겨주는 속성이 있다.
예를 들어 다음과 같이 설정했을 때,

source: '/old-blog/:slug',
destination: '/news',

source에서는 다이나믹 Path를 받았지만, destination 그 어디에도 받아온 slug를 사용하는 곳이 없다. 이런 경우 slug로 입력받은 값은 destination의 쿼리로 넘겨진다.

module.exports = {
  reactStrictMode: true,
  async rewrites() {
    return [
      {
        source: "/test/:slug",
        destination: "/episodes",
      },
    ];
  },
// Episodes.tsx
const Episodes: NextPage = () => {
  const router = useRouter();
  console.log(router.query);
  ...
}

만약 *를 이용해 여러 path를 받는 경우엔..?
/test/a/b/c/e/d 를 입력한 경우 배열로 해당 값을 받게 된다.

다른 속성들

기본적인 sourcedestination 속성 외에도 다양한 속성들이 있다.

has & missing

rewrite나 redirect를 path뿐만 아니라 헤더나 쿠키, 쿼리 값이 일치하거나(has) 일치하지 않는 경우(missing)에만 실행할 수 있도록 사용하는 속성

has에 있는 속성은 전부 일치해야하며
missing에 있는 속성은 전부 일치해선 안된다.

속성 타입

{
	type : 'header' | 'cookie' | 'host' | 'query',
    key : String,
    value : String | undefined
}

사용 예시

module.exports = {
  // rewrite
  async rewrites() {
    return [
      {
        source: '/:path((?!another-page$).*)',
          has: [
            {
              type: 'header',
              key: 'x-redirect-me',
            },
          ],
            permanent: false,
              destination: '/another-page',
      },
	  {
        source: '/:path((?!another-page$).*)',
        missing: [
          {
            type: 'header',
            key: 'x-do-not-redirect',
          },
        ],
        permanent: false,
        destination: '/another-page',
      },
      ]
  }
}

basepath

만약 module.exportsbasepath 설정을 해둔 경우, source path에 적용 여부를 나타낸다. false는 destination에 외부 링크가 사용된 경우에만 사용할 수 있는 속성이다.

module.exports = {
  basePath: '/docs',

  async redirects() {
    return [
      {
        source: '/with-basePath', // automatically becomes /docs/with-basePath
        destination: '/another', // automatically becomes /docs/another
        permanent: false,
      },
      {
        // does not add /docs since basePath: false is set
        source: '/without-basePath',
        destination: 'https://example.com',
        basePath: false,
        permanent: false,
      },
    ]
  },
}

permanent

✅ redirect에만 존재하는 속성값

permanent 속성값은 유저나 검색 엔진에서 해당 리다이렉트 값을 영구적으로 저장할 것인지에 대한 여부다. 만약 이벤트 페이지 이거나 임시 페이지인 경우는 false로 지정해주면 된다.

profile
PRE-FE에서 PRO-FE로🚀🪐!

4개의 댓글

comment-user-thumbnail
2023년 1월 18일

넘 유용하네요.. 잘 읽고 갑니당❣️

1개의 답글
comment-user-thumbnail
2023년 1월 19일

잘 읽었습니다

1개의 답글