Next.js의 App Router에서의 react-notion-x 라이브러리 적용기입니다.
+ 다국적 언어 지원 라이브러리인 react-i18next도 함께 사용하고 있습니다.
* 23.10.25 : 현재는 모노레포 구축 후 nextjs-notion-starter-kit으로의 라이브러리 교체가 되었습니다.
문제상황
- react-notion-x는 상세페이지 클릭시 자동으로 /{pageId} 경로로 redirection시킨다.
- 나의 경우는 경로에 동적 언어 라우팅도 포함되고 있었기 때문에 /[lng]/{pageId} 이런 식으로 경로가 설정되어야만 했다.
- lng는 en(영어), ko(한국어) 2개국어 지원
- 따라서 /en/{pageId} 또는 /ko/{pageId} 로 이동해야 함.
- 관련된 레퍼런스가 없음.
해결과정
1. next.config
처음에는 root폴더 위치에 있는 next.config.js에서 리다이렉션 설정을 해주는 것으로 문제가 간단히 해결될 줄 알았다.
- i18n과 관련하여 nextjs 공식문서에도 redirect 속성을 이용한 config 세팅에 대해 안내가 언급되어 있기도 하기 때문이다.
- 하지만, 내가 원하는 것은 /ko (한글 서비스 - 메인)에서 /{pageId}로 리다이렉션 시, 현재 언어 상태를 감지해서 /ko/{pageId}로 리다이렉션 시키는 것이었기 때문에 아래의 내용과는 전혀 관련이 없었다.
- 문서에 나와있는 다른 예시들 역시 비슷했으며 그나마 /{pageId}로 갔을때 현재 언어 상태와는 관련없이 한국어 서비스로만 리다이렉션 시키는 것까지는 성공했으나 그 다음에 다른 메뉴로 이동하게 되면 사이드 이펙트가 발생했다.
안 됐던 코드 예시
module.exports = {
async redirects() {
return [
{
source: '/:pageId', // 페이지 Id로 들어왔을 때
destination: '/ko/:pageId', // 중간에 :lng 등의 동적 값 입력이 안 됐으므로 ko로 고정시키고 pageId로 이동
permanent: false,
},
]
},
// 성공은 했으나 /ko/{pageId}에서 다시 홈으로 이동할 때 /ko만 나와야 하지만
// /ko/ko로 나오는 사이드이펙트 발생
}
2 SSR나 CSR에서 redirect?
- SSR이나 CSR에서 redirect 함수를 쓰면 된다.
- 그러나!!
- 내 프로젝트에서 현재 루트 페이지가 app/[lng]/pages.tsx 였기 때문에, 상세 페이지 데이터를 받아야 하는 정상적인 라우팅 폴더구조는 app/[lng]/[pageId]/pages.tsx가 된다.
- 즉, 아예 최상위 url이 / 가 아니라 /en 또는 /ko라는 뜻이다.
- / 로 들어가면 저절로 디폴트 언어인 /ko로 들어가게 된다.
- 그러나 노션 상세페이지 url은 /{pageId}로 app/[pageId]/pages.tsx로 들어가고 있었다.
- 따라서 애초에 리다이렉션을 시키려면 라우팅 구조에 맞게 pages.tsx파일이 위치해서 데이터를 만져야 하는데 루트 폴더가 app/[lng]였으므로 노션이 자동으로 링크시키는 url로는 데이터가 아예 들어가지 않는 구조적 문제가 있었다.
3. 📌 미들웨어 사용하기
- 결론적으로 middleware를 사용하여 해결했다! (공식문서)
- middleware은 말 그대로 중간에 실제 요청이 처리되기 전에, 어떤 작업을 하는 것으로 헤더를 수정하거나, 쿠키 생성 및 삭제, 리다이렉션 등 다양한 작업을 수행할 수 있다.
- 위치는 app 라우터와 동일한 위치에 생성하면 된다.
- 꼭 return을 넣어야 리다이렉션이 작동된다!
middleware.ts
import { NextRequest, NextResponse } from 'next/server';
const PUBLIC_FILE = /\.(.*)$/;
export function middleware(req: NextRequest) {
if (
req.nextUrl.pathname.startsWith('/_next') ||
req.nextUrl.pathname.includes('/api/') ||
PUBLIC_FILE.test(req.nextUrl.pathname)
)
return;
const supportedLocales = ['ko', 'en'];
// url 경로에 ko, en이 없으면
if (!supportedLocales.some((locale) => req.nextUrl.pathname.includes(locale))) {
// 쿠키에 저장되어 있는 최근 언어 상태를 가져와서
const locale = req.cookies.get('i18next')?.value || 'ko';
// 의도한 url 경로로 리다이렉션 시키면 된다.
return NextResponse.redirect(
new URL(`/${locale}${req.nextUrl.pathname}${req.nextUrl.search}`, req.url),
);
}
}
작동 확인
아래와 같이 서버에서 console.log(이동 url)을 찍어보았고 /{pageId}에 현재 언어 상태가 한국어면 /ko/{pageId}로 리다이렉션 시키는 것을 확인했다.
참고
- https://nextjs.org/docs/app/building-your-application/routing/middleware
- https://stackoverflow.com/questions/72607504/next-js-middleware-nextresponse-redirect-not-working-when-using-map-or-foreac
728x90
'📌 PROJECT > 2309 다국어 지원 포트폴리오' 카테고리의 다른 글
[Next.js 13] SSR로 동적 meta태그 생성하기 (app router) (0) | 2023.10.20 |
---|---|
pnpm을 이용한 모노레포 마이그레이션 (0) | 2023.10.18 |
NotionAPI로 블로그 만들기 (2) react-notion-x로 노션 데이터베이스 불러오기 (Next.js App Router) (0) | 2023.10.11 |
NotionAPI로 블로그 만들기 (1) nextjs-notion-starter-kit vs react-notion-x (0) | 2023.10.11 |
[CI/CD] lint-staged, husky로 린트 검사 자동화하기 (+Jest test) (0) | 2023.10.02 |