Next의 Redirect | next.config, Middleware
2022. 10. 28. 00:44ㆍWeb_Programming/Next
이전 포스팅에서 "CSR에서 렌더링 전에 redirect가 가능한가"에 대해 알아봤습니다.
이 외에도 Next js의 redierct 방식들을 찾아보면서 더 다양한 방법으로 redirect를 제공한다는 것을 알게 되어 다시 포스팅을 해보게 되었습니다.
알게 된 redirect 방식은 크게 3가지가 있습니다.
- next.config.js
- middleware
- ServerSide (getServerSideProps, getStaticProps)
하나씩 자세히 살펴보겠습니다.
next.config | Redirects
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 파라미터가 유지되는 게 큰 단점으로 느껴져서 원인을 찾아보다가,
아래와 같은 이슈 내용을 발견했습니다.
이는 현재 요청의 쿼리 값이 대상으로 전달되어 context utm_source 및 기타 쿼리 매개변수가 redirection에서 손실되지 않도록 하기 위해 유지된다.
라고 설명하고 있어요.
현재 지원이 안 되는 작업이고 이에 대한 방안으로 Middleware의 Redirect를 사용하라고 나와있습니다.
Middleware | Redirects
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 미들웨어는 사이트에서 요청이 처리되기 전에 실행되는 코드입니다.
캐시보다 먼저 실행되기 때문에 미들웨어를 사용하는 것은 정적으로 생성된 콘텐츠에 개인화를 제공하는 효과적인 방법입니다.
들어오는 요청에 따라 응답을 반환하기 전에 사용자 지정 논리를 실행하고, 다시 작성하고, 리디렉션 하고, 헤더를 추가하는 등의 작업을 수행할 수 있습니다.
Edge Middleware를 사용하면 방문자의 오리진에 가까운 Edge로 서버 측 논리를 이동할 수 있습니다.
수행 순서
이 외에도 config와 middleware 간의 수행 순서 또한 궁금했는데 docs에서 제공한 바로는 아래의 순서대로 수행이 됩니다.
속도 비교
실제로 load 속도를 비교해봤습니다.
🥇next.config | 4ms
🥈Middleware | 8ms
🥉getServerSideProps | 16ms
결과적으로, query 파라미터 유지 없이 redirect 시키고자 했던 저는 Middleware를 이용하여 50%의 속도 개선을 해낼 수 있었습니다!
이 기회에 여러 Redirect 방식과 실행 원리, 순서, 속도 등 자세하게 공부해 볼 수 있어 좋았던 것 같습니다
'Web_Programming > Next' 카테고리의 다른 글
카카오 로그인 with Next 13, react-query, strapi (0) | 2023.05.29 |
---|---|
Next router 이동 막기 _알림창 (1) | 2022.12.04 |
Next의 Pre-rendering과 함수들 (0) | 2022.11.01 |
ClientSide에서 rendering 전 redirect 가능한가? (0) | 2022.10.06 |