Next.js 동적 라우팅에서 메타데이터 생성하기

힘센캥거루
2024년 12월 16일
4
28

검색엔진 최적화를 위해 metadata를 어떻게 넣을까 검색을 하다가 velog에서 Doeunnkimm님의 글을 보고 메타데이터를 정적으로 주입하고 있었다.

포스팅을 시작하니 동적 라우팅에서 각 포스트마다 다른 metadata를 넣고 싶었다.

그래서 복습하는 겸 한번 써본다.

1. 코드

먼저 위의 velog에서 구한 코드는 아래와 같다.

// 먼저 기본적으로 필요한 메타 데이터를 설정한다.
const META = {
  title: "블로그 제목",
  siteName: "사이트이름",
  description: "블로그에 대한 대략적인 설명",
  keyword: ["배열", "형태의", "키워드"],
  url: "https://sample.kr",
  googleVerification: "xxx", //구글 서치콘솔
  naverVerification: "xxx", //네이버 서치어드바이저
  ogImage: "https://sample.kr/assets/thumbnail.png", // 썸네일,
} as const;

// getMetadata 함수를 이용해 metadata를 설정한다.
// 아래 함수 하나면 대부분의 사이트에서 필요한 metadata는 끝난다.
export const getMetadata = (metadataProps?: generateMetadataProps) => {
  const { title, description, asPath, ogImage } = metadataProps || {};

  const TITLE = title ? `${title} | 블로그 제목` : META.title;
  const DESCRIPTION = description || META.description;
  const PAGE_URL = asPath ? asPath : "";
  const OG_IMAGE = ogImage || META.ogImage;

  const metadata: Metadata = {
    metadataBase: new URL(META.url),
    alternates: {
      canonical: PAGE_URL,
    },
    title: TITLE,
    description: DESCRIPTION,
    keywords: [...META.keyword],
    openGraph: {
      title: TITLE,
      description: DESCRIPTION,
      siteName: TITLE,
      locale: "ko_KR",
      type: "website",
      url: PAGE_URL,
      images: {
        url: OG_IMAGE,
      },
    },
    verification: {
      google: META.googleVerification,
      other: {
        "naver-site-verification": META.naverVerification,
      },
    },
    twitter: {
      title: TITLE,
      description: DESCRIPTION,
      images: {
        url: OG_IMAGE,
      },
    },
    icons: {
      icon: "/favicon/favicon.ico",
    },
  };

  return metadata;
};

그리고 해당 코드를 layout.tsx에서 호출해서 사용한다.

metadata를 생성하고 이를 export 해주면 홈페이지에 대한 메타 데이터를 생성한다.

import "./globals.css";
import { Metadata } from "next";
import { getMetadata } from "@/utils/getMetadata";

// 메타데이터 객체를 내보냄
export const metadata: Metadata = {
  // 전개연산자 ..,를 이용해 객체를 가져온다.
  ...getMetadata(),

  // 만일 다른 제목을 쓰고 싶다면 아래와 같이 하면 된다.
  ...getMetadata({ title: "다른제목" }),
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="ko">
      <body className="h-svh">
        <div>
          <div className="mx-auto max-w-7xl p-6 lg:px-8">{children}</div>
        </div>
      </body>
    </html>
  );
}

자신의 홈페이지로 들어가 F12키를 누른 뒤, <head> 태그를 살펴보면 meatadata를 확인할 수 있다.

Next.js 동적 라우팅에서 메타데이터 생성하기-1

2. 동적 라우팅과 metadata

동적 라우팅에서는 generateMetadata 함수를 이용했다.

이에 대한 설명은 위의 블로그나 Nextjs 공식문서에 있다.

Next.js 동적 라우팅에서 메타데이터 생성하기-2

이 글의 핵심은 metadata를 만들 때 동적 라우팅에 이용되는 객체를 이용할 수 있다는 것이다.

나는 slug와 글 목록이 있는 Json을 이용해 메타 데이터를 만들었다.

export async function generateMetadata({
  params,
}: {
  params: { slug: string };
}) {
  const { slug } = await params;

  //카테고리 목록 json을 호출함
  const categoryData = fs.readFileSync(categoryJsonPath, "utf-8");
  const categorys: postCardFrontMatter[] = JSON.parse(categoryData);

  // 현재의 slug와 url이 동일한 것을 1개 찾아 반환함.
  const baseMetaData = categorys.find(
    (category) => category.postUrlPath === slug
  );

  //이것을 이용해 메타데이터 설정
  const metadata: Metadata = {
    ...getMetadata({
      title: baseMetaData?.data.title,
      description: baseMetaData?.data.description,
      asPath: `https://earthscience.kr/posts/${slug}`,
      ogImage:
        baseMetaData?.data.thumbnail &&
        `https://earthscience.kr/posts/${slug}/${baseMetaData.data.thumbnail}`,
    }),
  };
  return metadata;
}

3. 후기

보통 페이스북의 공유 디버거를 많이들 활용한다.

그런데 나는 페이스북 아이디가 없어서 그냥 카톡으로 테스트를 해보았다.

단점은 이미지가 뜨기까지 시간이 좀 오래 걸린다.

Next.js 동적 라우팅에서 메타데이터 생성하기-3

처음에는 사진이 보이지 않다가 다음날 다시 들여다보니 사진이 잘 뜬다.

하나씩 만들어가는 재미가 있는것 같다.

관련 글

Next.js 풀스택 블로그 개발기
Next.js 풀스택 블로그 개발기
웹개발을 처음 접한지 1년정도 되었을 때, 나만의 블로그를 갖고싶다는 생각을 하게 되었다.그래서 6개월 정도 여기에만 매달려서 만들어보게 되었다.프론트 앤드에서의 기능은 아래 김도형님의 블로그를 참고하는 것으로 충분할 듯하다.나도 mdx를 이용해 블로그를 만드는데는 채...
Caddy를 이용한 Nextjs 무중단 배포(로컬서버)
Caddy를 이용한 Nextjs 무중단 배포(로컬서버)
홈페이지에 뭔가 자꾸 얹고 싶은 욕심이 들 때 마다 빌드를 했더니, 그 사이에 가끔 접속하는 사람이 종종 있긴 한것 같다.그러다 보니 서치콘솔에서 점수가 점점 하락하는 현상이 발생했다.이대로는 안될 것 같아 무중단 배포를 하는 방법을 생각해 보게 되었다.1. 대표적인 ...
구글 검색 색인 자동화 - Web Search Indexing API
구글 검색 색인 자동화 - Web Search Indexing API
지난번 IndexNow에 이어, 구글도 자동화를 해보기로 했다.찾아보니 구글은 API로 Web Search Indexing이라는 걸 지원하고 있었다.1. 허용범위공식적으로 해당 API가 지원하는 범위는 채용공고와 스트리밍 영상 서비스이다.실시간이 중요한 내용에 대해 색...
검색 색인 생성 자동화 - IndexNow
검색 색인 생성 자동화 - IndexNow
Bing에 검색등록을 하다가 알게 되었는데, Bing에서는 IndexNow라는 기능을 제공한다.핵심은 API 키를 이용해서 글을 쓰자마자 바로 색인 요청을 날릴 수 있다는 것.아래와 같은 요청을 fetch로 만들고, 글쓰기에 연동해 놓으면 글을 DB에 저장함과 동시에 ...
Nextjs, React 서버 해킹당한 경험 - React2Shell
Nextjs, React 서버 해킹당한 경험 - React2Shell
맨 처음 보안 이슈를 접했던건 12월 5일 새벽이었다.리액트에서 인증 없이 원격 코드 실행이 가능하다는 것.해당 뉴스를 접하고 다른 사람에게 알렸지만, 나는 괜찮으려니 싶어 아무 생각없이 넘겼다.1. 해킹 흔적 발견그런데 블로그 코드를 업데이트 하려고 접속했더니 터미널...
블로그에 다국어 기능 추가하기(NextJS, next-intl, Vercel AI SDK)
블로그에 다국어 기능 추가하기(NextJS, next-intl, Vercel AI SDK)
최근 블로그에 다국어 기능이 필요하다는 생각이 들었다.그래서 next-intl을 이용해 다국어 서비스를 구현해보기로 했다.1.i18n먼저 다국어 서비스를 할 때는 지켜야 할 원칙들이 있다.이걸 internationalization이라고 하는데, 무척 길기에 첫글자 i와...

댓글을 불러오는 중...