[Next] middleware를 사용해 redirect 하기 (feat. url path sync 맞추기)

mogooee·2024년 5월 7일
0

최근 진행중인 프로젝트에서 url에 검색 키워드를 포함시켜 SEO를 최적화하는 작업을 진행해야했다.

기존 : {base_url}/real-estate/{agency_id}
변경 : {base_url}/real-estate/{agency_id}/{agency_seo_key}

ex) https://develop.com/real-estate/1/000공인중개사사무소-서울시강남구-000

문제점

기존에도 url에 id와 name 부가정보를 함께 담는 방법을 고려한 적이 있었다.
리뷰 작성페이지는 리뷰 작성 API를 호출하기 위한 공인 중개사 ID 값과 화면에 표시할 공인중개사 name 값이 필요하다.

이를 위해 URL의 path와 query에서 값을 파싱하여 사용했다. 
ex) reviews/new/1?n=00공인중개사사무소

그러나 이러한 방식은 다음과 같은 문제점으로 인해 url에 id만 담는 방식으로 변경되었다.

 1. 공인 중개사에 대한 정보가 불필요하게 중복되어 담겨있고 

 2. id나  name 값을 URL로 조작시 에러가 발생할 수 있다.

해결책

위의 문제점의 1번은 SEO 개선을 위해 수행되어야 하는 작업으로 의문점이 해결되었다.
2번을 해결하기 위해 다른 사이트를 참고해보았더니 id에 따라 name이 변경되며 redirect가 발생하고 있었다.

예를 들어 id가 1인 공인중개사는 000공인중개사사무소-서울시강남구-000 라는 seo key를 가지고 있다.
하지만 사용자가 임의적으로 주소창의 id를 바꾸거나 seo key를 바꾸는 경우가 생길 수 있다.

ex)

  1. 정상적인 url
    https://develop.com/real-estate/1/000공인중개사사무소-서울시강남구-000

  2. id를 변경한 url
    https://develop.com/real-estate/10/000공인중개사사무소-서울시강남구-000

  3. seo key를 변경한 url
    https://develop.com/real-estate/1/000공인중개사사무소-용인시수지구-000

Catch-all Segments

우선 id 뒤의 path가 붙어도 detail 페이지를 렌더링하므로 파일 이름을 catch-all segements를 사용해 [...id.tsx] 로 변경한다.

  • 변경 전: [id.tsx]
    • real-estate/1 (O)
    • real-estate/1/000공인중개사무소 (X)
  • 변경 후: [...id.tsx]
    • real-estate/1 (O)
    • real-estate/1/000공인중개사무소 (O)

middleware

Next는 middleware를 사용해 네트워크 요청을 가로채고 응답을 받기 전 redirect 시킬 수 있다.

root 디렉토리(/src)에 middleware.ts를 생성하고 다음 로직을 작성한다.

  1. request url의 pathname 중에 id와 seo key를 파싱한다.

  2. id를 이용해 API 요청으로 올바른 seo key를 얻는다.

  3. request url의 seo key와 API 응답으로 얻은 seo key가 같지 않은 경우 올바른 seo key의 url로 리다이렉트 한다.

import { NextResponse, type NextRequest } from 'next/server'
import { getRealEstateData } from './apis/realEstateApis'

export const middleware = async (request: NextRequest) => {
  const [_x, _y, id, seo_key] = decodeURI(request.nextUrl.pathname).split('/')
  const agencyData = await getRealEstateData(Number(id))
  if (agencyData.seo_key !== seo_key) {
    return NextResponse.redirect(new URL(`/real-estate/${id}/${agencyData.seo_key}`, request.url))
  }
}

export const config = {
  matcher: '/real-estate/:id*',
}

결론

네트워크 요청을 가로채서 잘못된 url 주소인 경우 리디렉션을 한다.
이를 통해 원하는 응답 리소스를 시간 낭비없이 빠르게 얻을 수 있다.

profile
개발의 숲

0개의 댓글

관련 채용 정보