본문 바로가기

[Next.js 13] SSR로 동적 meta태그 생성하기 (pages router)

[Next.js 13] SSR로 동적 meta태그 생성하기 (pages router)
[ 상황 ]
- /user/profile/[userId] -> 동적 라우팅으로 특정한 유저의 페이지로 접속하는 상황
- 유저 페이지 자체는 유저가 쓴 게시글 페이지보다는 SEO 중요도는 다소 떨어지지만, 추후 확장을 위해 이미 개발해둔 동적 페이지에서 기능을 구현
- 마이 페이지와 유저 페이지는 한 컴포넌트를 공유하여 사용
  (전역에 저장된 나의 loginId와 동적 라우팅으로 접속한 페이지에서 params로 추출한 userId를 비교하여 분기 처리)

[ 개발 환경 ]
- nextjs는 pages router 구조로 개발 중이며 데이터 요청은 Tanstack-Query를 사용합니다.
- 관련 포스팅 : [Next.js 13] SSR로 동적 meta태그 생성하기 (app router)

 

구현 기능

 

마이 페이지일 때 메타 태그 (정적 데이터)

 

유저 페이지일 때 메타 태그 (동적 데이터)

 

코드 작성 

 

확인해야 할 것 

_app.tsx에 아래와 같이 pageProps가 잘 전달되고 있는지 확인한다.

  • 모든 컴포넌트가 렌더링 될 때는 이 _app.tsx를 먼저 거쳐가며, 여기서 pageProps에 SSR로 받아온 데이터가 우리가 렌더링할 컴포넌트까지 흘러 들어간다. 
  • (만약 만약에) 초기세팅 때 삭제했다면 다시 살려두자..! 
  • nextjs pages 폴더 구조 기준이다.

 

_app.tsx
const App = ({ Component, pageProps }: AppProps) => {
.
.
.
.

  return (
.
.
.
                      <Component {...pageProps} />

.
.
.

 

getServerSideProps 

 

109번째 줄의 props로 내 보내는 userId의 값은 UserPage 컴포넌트에서 받아올 수 있다. 

  • 콘솔을 찍어보면 터미널의 서버 단에서 userId인 'doyu'가 출력되는 것을 확인할 수 있다.

 

SSR에서 QueryClient를 생성하고, prefetchQuery를 사용해서 기존 회원정보 불러오기 query문을 작성한다.

  • apiUser.ts 코드 54번째 줄 참고 (밑에 있음)

 

 

apiUser.ts

 

1. UserPage 컴포넌트 내에서는 SSR에서 받아온 userId로 마이 페이지 여부 함수를 작동시킨다. (16번째 줄)

  • 이 때, loginId와 userId가 같으면 /user/mypage로 이동한다.
  • loginId : redux/toolkit에 저장된 전역 로그인한 유저의 ID 데이터
  • userId: SSR로 받아온 동적 페이지에서 해당 유저의 ID 데이터 

 

2. UserPage 컴포넌트 내에서 기존의 query말고, SSR 회원정보 불러오기(60번째 줄) query로 SSR에서 캐싱된 데이터를 가져온다.

import { QueryClient, dehydrate } from '@tanstack/react-query';
import type { GetServerSideProps } from 'next';
import { ParsedUrlQuery } from 'querystring';
.
.
.

const UserPage({ userId: userIdParam }: { userId: string }) {
  const { isLoggedIn, loginId: globalLoginId } = useUserGlobalValue();

  useCheckIsMyPageFirst({ userIdParam, globalLoginId });
  
  const {
    isLoading: isUserPageLoading,
    error: isUserPageError,
    data: userPageData,
  } = apiUser.useGetUserPage(userIdParam);
.
.
.

export default UserPage;


// 🟣 서버에서 이미 데이터까지 fetch해온 상태에서 렌더링 진행 (SSR)

interface Params extends ParsedUrlQuery {
  userId?: string | string[];
}

// 동적으로 추출해온 userId 타입은 아래와 같이 ParsedUrlQuery에서 확장된 Params로 지정해주었다.

export const getServerSideProps: GetServerSideProps = async ({ params }) => {
  const { userId }: Params = params || { userId: undefined };
  const queryClient = new QueryClient();
  await queryClient.prefetchQuery(['userPage'], () => apiUser.getUserPage(userId));

  return {
    props: {
      userId,
      dehydratedState: dehydrate(queryClient),
    },
  };
};

 

그러면 이렇게 userId와 해당 유저에 해당되는 유저 정보를 잘 받아오는 것을 확인할 수 있다.

 

메타 태그 생성하기 

 

  • 마이페이지일 때는 HeadMeta에 마이 페이지 관련 상수 값을 넣는다. (정적인 값)
  • 유저페이지일 때는 HeadMetadp 동적으로 받아온 userPageData의 해당 유저 nickname 값을 넣는다.
.
.
.
  return (
.
.
.   {isMyPage ? (
        <HeadMeta title={USER_META_DATA.MY_PAGE.TITLE} description={USER_META_DATA.MY_PAGE.DESCRIPTION} />
      ) : (
        <HeadMeta
          title={USER_META_DATA.USER_PAGE.TITLE}
          description={`제로힙 ${userPageData?.nickname}님의 페이지입니다`}
        />
      )}
.
.
.
.

 

이렇게 하면 아래와 같이 닉네임이 출력되는 것을 확인할 수 있다!

 

참고

- https://hojung-testbench.tistory.com/entry/NextJs-React-Query%EB%A1%9C-ServrSide-Rendering-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0

728x90
⬆︎