Next.js 14 에서 동적 메타데이터 적용하기

D uuu·2024년 7월 11일
0

Next.js14 프로젝트

목록 보기
11/15

Next.js 로 구현하면서 이번에는 꼭 메타데이터를 적용해봐야겠다는 생각이 있었다! 왜냐하면 초보 개발자 입장에서는 글로만 접하는 SEO 가 도저히 이해가 안됐기 때문이다.

메타데이터는 뭐고 그게 왜 SEO 에 도움이 되는지 등 해보지 않고서는 반쪽자리 지식이라는 생각이 들었고, 때마침 Next.js 14 로 프로젝트를 구현하기로 결정하면서 Next.js 14 의 업그레이드 된 기능을 사용해 동적 메타데이터를 구현해 SEO 최적화 작업을 해보기로 했다😆

먼저 비교사진😎 (메타데이터 적용 전 & 후)

메타데이터를 적용하기 전과 후 모습을 비교해봤을때, 적용하기 전에는 어떤 사이트인지 불분명해 보인다. 이미지도 없고 사이트에 대한 소개도 없으니 눌러보기가 꺼려지기도 하는데, 확실히 이미지와 더불어 사이트 정보를 제공하니 더 눈길이 가고 신뢰가 생기는 효과가 있다.

따라서 메타데이터를 잘 사용하면 사람들의 시선을 더 끄는 사이트로 만들 수 있고, 유입이 많아지면 그에 따른 기대 수익이 생겨날 수 있으니 매우 중요한 기능이라 할 수 있다.

메타태그 작성하기

메타 태그를 설정하는 방법으로는 HTML 코드를 작성할때 <head> 태그에 내용을 입력해주면 되는데, Next.js 는 metadata 기능을 제공해주기 때문에 아래와 같이 일일이 작성해주지 않아도 된다!

<head>
<title>먹기록 - 매일 다른 음식을 기록하고 공유하세요</title>
<meta name="description" content="먹기록은 매일 먹은 음식과 음식점을 기록하고, 팔로우한 사람들과의 음식 일상을 공유하는 사이트입니다. 다양한 음식 경험을 기록하며 하루의 특별한 순간을 기억하세요."/>
<meta name="keywords" content="음식,일상,일기,공유,추억,맛집"/>
<link rel="canonical" href="https://omuk-beta.vercel.app"/>
<meta name="naver-site-verification" content="26f9b328438f88ca40b4d18c011e8a5cd0311d05"/>
<meta property="og:title" content="먹기록 - 매일 다른 음식을 기록하고 공유하세요"/>
<meta property="og:description" content="먹기록은 매일 먹은 음식과 음식점을 기록하고, 팔로우한 사람들과의 음식 일상을 공유하는 사이트입니다. 다양한 음식 경험을 기록하며 하루의 특별한 순간을 기억하세요."/>
<meta property="og:url" content="https://omuk-beta.vercel.app"/>
<meta property="og:site_name" content="먹기록 - 매일 다른 음식을 기록하고 공유하세요"/>
<meta property="og:locale" content="ko_KR"/><meta property="og:image" content="https://s3-omuk-images.s3.ap-northeast-2.amazonaws.com/main.png"/>
<meta property="og:type" content="website"/>
<meta name="twitter:card" content="summary_large_image"/>
<meta name="twitter:title" content="먹기록 - 매일 다른 음식을 기록하고 공유하세요"/>
<meta name="twitter:description" content="먹기록은 매일 먹은 음식과 음식점을 기록하고, 팔로우한 사람들과의 음식 일상을 공유하는 사이트입니다. 다양한 음식 경험을 기록하며 하루의 특별한 순간을 기억하세요."/>
<meta name="twitter:image" content="https://s3-omuk-images.s3.ap-northeast-2.amazonaws.com/main.png"/>
</head>

metadata

대신 이런식으로 metadata 를 사용하면 title, description 등을 설정할 수 있다. metadata 는 page, layout 에서만 작성이 가능하고 서버 컴포넌트에서만 작성 할 수 있다. 즉, 'use client' 로 작성한 컴포넌트는 사용이 불가능하다!

export const metadata: Metadata = {
    title: {
        template: '%s | MUKIROK',
        default: 'MUKIROK',
    },
     description: '먹기록은 매일 먹은 음식을 기록하고, 팔로우한 사람들과의 음식 일상을 공유하는 사이트입니다. 다양한 음식 경험을 기록하며 하루의 특별한 순간을 기억하세요.',
};

동적 메타데이터 생성하기

페이지 별로 콘텐츠에 따라 메타데이터도 다르게 표시하고 싶을 수 있다. 그때 사용하는 것이 바로 generateMetadata 함수이다.
음식점 별로 title 에는 음식점 이름을 description 에는 음식점 소개를 표시하고 싶었기에 나는 동적 메타데이터를 이용해 아래와 같이 구현했다.

요런식으로 음식점을 클릭할때마다 '음식점 이름 | 먹기록' 으로 음식점 이름이 바뀌는 걸 볼 수 있다👇👇

export const generateMetadata = async ({ params: { id } }: ParamType) => {
    const post = await getDetail(id);

    return {
        title: post.title,
        description : post.content
    };
 };

유연하게 작성해보자

지금까지는 메타데이터를 title, description 만 작성했는데, 소셜 네트워크 등에 사이트를 공유할때 사이트 이미지와 소개글이 나타나도록 Open Graph 을 추가해보자
Open Graph 을 등록하면 아래와 같이 공유할때 메인 이미지와 블로그 제목이 함께 보내져 어떤 글인지 한눈에 알 수 있다.

기본 META 데이터 상수로 작성하기

메타데이터를 구성하는 데이터를 META 상수로 작성해줬다. 이런식으로 상수화 해주면 변경이 필요할때 META 데이터만 수정해주면 되니 관리가 용이하다는 장점이 있다.

export const META = {
    title: '먹기록 - 매일 다른 음식을 기록하고 공유하세요',
    description:
        '먹기록은 매일 먹은 음식을 기록하고, 팔로우한 사람들과의 음식 일상을 공유하는 사이트입니다. 다양한 음식 경험을 기록하며 하루의 특별한 순간을 기억하세요.',
    keyword: ['음식', '일상', '일기', '공유', '추억', '맛집', '맛집추천'],
    siteName: 'MUKIROK | 먹기록',
    url: 'https://omuk-beta.vercel.app',
    ogImage: 'https://s3-omuk-images.s3.ap-northeast-2.amazonaws.com/main.png',
    naverVerification: 'naver 검증 코드 작성',
    googleVerification: 'google 검증 코드 작성',
};

metadata 를 만드는 함수 작성하기

기본적인 META 데이터를 만들었으니 이제 메타데이터를 생성해주는 함수를 만들었다. 유연한 사용을 위해 props 로 필요한 정보를 받을 수 있도록 했고, 만약 없다면 기본값을 가지도록 작성했다.

export const getMetadata = (metadataProps?: MetaDataType) => {
    const { title, description, ogImage, asPath } = metadataProps || {};

    const TITLE = title ? `${title} | 먹기록` : META.title;
    const DESCRIPTION = description || META.description;
    const PAGE_URL = asPath || META.url;
    const OG_IMAGE = ogImage || META.ogImage;

    const metadata: Metadata = {
        metadataBase: new URL(META.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,
            },
        },
    };

    return metadata;
};

적용하기

이제 위에서 하드코딩 했던 로직을 getMetadata 로 수정해줬다. 그러고 나서 카카오톡에 공유해보니 아래와 같이 메인 표지와 음식점 별로 사이트에 접속했을때의 미리보기가 잘 구현된 걸 볼 수 있다!!😎

app/layout.tsx

export const generateMetadata = () => {
    return getMetadata();
};
app/[id]/layout.tsx

export const generateMetadata = async ({ params: { id } }: ParamType) => {
    const post = await getDetail(id);

    return getMetadata({
        title: post.basicInfo?.placenamefull,
        description: post.basicInfo?.category.catename,
        ogImage: post.basicInfo?.mainphotourl,
        asPath: `/${id}`,
    });
};

Reference !!

profile
배우고 느낀 걸 기록하는 공간

0개의 댓글