Next의 Redirect | next.config, Middleware

2022. 10. 28. 00:44Web_Programming/Next

이전 포스팅에서 "CSR에서 렌더링 전에 redirect가 가능한가"에 대해 알아봤습니다.

https://keeper.tistory.com/54

 

ClientSide에서 rendering 전 redirect 가능한가?

Next 를 이용하여 파라미터의 유효성을 검사하여 리다이렉트 시키는 과정에서 고민이 생겨 간단하게 포스팅을 남겨보려 합니다. 요구사항은 페이지가 렌더되기 전에 유효성을 검사하여 /404 로

keeper.tistory.com

 

 

이 외에도 Next js의 redierct 방식들을 찾아보면서 더 다양한 방법으로 redirect를 제공한다는 것을 알게 되어 다시 포스팅을 해보게 되었습니다.


알게 된 redirect 방식은 크게 3가지가 있습니다.

  • next.config.js 
  • middleware 
  • ServerSide (getServerSideProps, getStaticProps) 

 

하나씩 자세히 살펴보겠습니다.


next.config | Redirects

 

next.config.js: Redirects | Next.js

Add redirects to your Next.js app.

nextjs.org

next.config 파일의 module.exports 파트에 redirects를 선언함으로써 특정 source의 path를 redirect 시킵니다.

redirect를 원하는 source는 pathMatching regx로 특정지을 수 있습니다.

module.exports = {
  async redirects() {
    return [
      {
        source: '/post/:slug(\\d{1,})',
        destination: '/news/:slug', // Matched parameters can be used in the destination
        permanent: false,
      },
    ]
  },
}

기본 path 외에도 Header, Cookie, and Query Matching으로 redirect 시킬 수 있습니다.

query의 유효성 검사 후 redirect를 시키고자 했던 저는 이 방법으로 시도해보고자 했습니다.

 

+ 여기서 key 값이 query 파라미터의 key 값을 뜻하고 value가 해당 쿼리의 redirect 대상이 됩니다.

+ 여기서 value값에 regx를 사용하여 QueryMatching을 적용할 수 있습니다.

module.exports = {
  async redirects() {
    return [
      {
        source: '/specific/:path*',
        has: [
          {
            type: 'query',
            key: 'page',
            // the page value will not be available in the
            // destination since value is provided and doesn't
            // use a named capture group e.g. (?<page>home)
            value: '/^[0-9]/',
          },
          {
            type: 'query',
            key: 'limit',
            value: '/^[0-9]/',
          },
          {
            type: 'cookie',
            key: 'authorized',
            value: 'true',
          },
        ],
        permanent: false,
        destination: '/another/:path*',
      },
    ]
  },
}

 

하지만 이 방식의 한계점이 존재했습니다.

바로 redirect 후에도 query 파라미터가 url에 유지된다는 점입니다.

 

/400 으로 redirect 시키고자 했던 저는 query 파라미터가 유지되는 게 큰 단점으로 느껴져서 원인을 찾아보다가,

아래와 같은 이슈 내용을 발견했습니다.

 

 

Trying to redirect with a 'query' type - does not remove the querystring from the redirect. · Issue #28231 · vercel/next.js

What version of Next.js are you using? 10.2.3 What version of Node.js are you using? 12.14.0 What browser are you using? Chrome What operating system are you using? OSX How are you deploying your a...

github.com

이는 현재 요청의 쿼리 값이 대상으로 전달되어 context utm_source 및 기타 쿼리 매개변수가 redirection에서 손실되지 않도록 하기 위해 유지된다.

라고 설명하고 있어요. 

 

현재 지원이 안 되는 작업이고 이에 대한 방안으로 Middleware의 Redirect를 사용하라고 나와있습니다.

 

 

Middleware | Redirects

 

Advanced Features: Middleware | Next.js

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

nextjs.org

middleware에서 config matcher의 path로 filtering 하여 redirect 시킵니다.

matcher는 next.config와 마찬가지로 regx로 활용이 가능합니다.

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

// This function can be marked `async` if using `await` inside
export function middleware(req: NextRequest) {
    const page = req.nextUrl.searchParams.get("page");
    const pageRgx = /[^0-9]/;
    if (page && pageRgx.test(page)){
    	return NextResponse.redirect(new URL("/404", req.url));
    }
}

// See "Matching Paths" below to learn more
export const config = {
  matcher: '/about/:path*',
}

+ 위 와 같이 query는 NextRequest로부터 얻을 수 있습니다.

 

해당 작업 시 중요한 점은 next와 eslint-config-next를 12.2 이상으로 업그레이드해주어야 정상 작동됩니다!

 

그런데 이 방법 또한 서버사이드에서 진행되는 작업이며, getServersideProps에서 redirect 시키는 것과 비교했을 때 Server - Client의 latency를 개선할 수 있는 방법인가에 대한 의문이 들었습니다.

 

찾아보니 해당 Middleware는 Edge 기반의 함수로 사용자와 가까운 별도의 Edge 서버에서 로직을 대신 수행함으로써, 기존 서버사이드의 지연시간을 줄이도록 고안되었다고 합니다.

 

 

Edge Middleware Overview

Learn how you can use Edge Middleware, code that executes before a request is processed on a site, to provide speed and personalization to your users.

vercel.com

 

간단하게 요약하면 아래와 같이 설명하고 있습니다.

Edge 미들웨어는 사이트에서 요청이 처리되기 전에 실행되는 코드입니다.
캐시보다 먼저 실행되기 때문에 미들웨어를 사용하는 것은 정적으로 생성된 콘텐츠에 개인화를 제공하는 효과적인 방법입니다. 
들어오는 요청에 따라 응답을 반환하기 전에 사용자 지정 논리를 실행하고, 다시 작성하고, 리디렉션 하고, 헤더를 추가하는 등의 작업을 수행할 수 있습니다.
Edge Middleware를 사용하면 방문자의 오리진에 가까운 Edge로 서버 측 논리를 이동할 수 있습니다.

수행 순서

이 외에도 config와 middleware 간의 수행 순서 또한 궁금했는데 docs에서 제공한 바로는 아래의 순서대로 수행이 됩니다.


속도 비교

실제로 load 속도를 비교해봤습니다.

🥇next.config  | 4ms

🥈Middleware | 8ms

🥉getServerSideProps | 16ms

 

결과적으로, query 파라미터 유지 없이 redirect 시키고자 했던 저는 Middleware를 이용하여 50%의 속도 개선을 해낼 수 있었습니다!

 

이 기회에 여러 Redirect 방식과 실행 원리, 순서, 속도 등 자세하게 공부해 볼 수 있어 좋았던 것 같습니다 

반응형