본문 바로가기
이론/Frontend

Next.js로 metadata 구성하기

by 유세지 2023. 9. 24.

 

 

 

얼마 전 작은 규모의 신규 프로젝트에 프론트엔드로 참여할 기회가 생겼습니다. 프로젝트 특성상 외부에 노출되는 빈도 수가 매출에 큰 영향을 끼치기때문에 SEO(Search Engine Optimization, 검색 엔진 최적화)가 굉장히 중요한 요소가 되었습니다.

 

그 중에서도 페이지가 갖고 있는 메타데이터(Metadata)는 SEO에 있어 가장 중요한, 빼놓을 수 없는 요소입니다. 그러나 우리가 주로 사용하던 React.js의 일반적인 CSR 방식으로는 이러한 수요를 만족하는데 한계가 있었습니다. 그러한 이유로 SEO에 유리한 Next.js를 선택하게 되었는데, 오늘 포스팅에서는 Metadata에 대해 알아보고 이를 통하여 어떻게 SEO를 향상시킬 수 있는지 알아보겠습니다.

 

 

 

SEO

SEO 수준을 결정하는 요소는 비단 메타데이터 뿐만은 아닙니다. 구글의 Lighthouse에서 제공하는 Chrome for Developers의 SEO Audits 문서를 참고하면, 검색 엔진 최적화 정도를 검사하기 위한 몇 가지 요소들을 확인할 수 있습니다.

 

이 중에서 우리가 오늘 알아볼 요소와 가장 가까운 것은 Document does not have a meta description(문서에 메타 설명이 없음) 문서입니다.

 

좋은 meta description에 대한 예시가 있습니다.

 

문서의 내용을 정리하면, 결국 아래 원칙들을 지킬 것을 권고하고 있습니다.

 

  • 각 페이지별로 상세한 설명을 사용할 것
  • 명확하고 간결하되, 모호한 표현은 피할 것
  • 키워드 스터핑을 사용하지 말 것

 

익숙하지 않은 용어가 있는데, 여기서 말하는 키워드 스터핑이란 검색 엔진에서 상위에 노출되기 위해 동일한 키워드를 다량 반복하는 것을 의미합니다. 아래 캡쳐가 바로 키워드 스터핑의 대표적인 예시입니다.

 

 

korean lorem ipsum 스타크래프트 1.16.1이 바로 키워드 스터핑입니다.

 

 

이렇게 의미없이 특정 키워드를 반복하는 경우 스팸으로 처리될 수 있으니 메타데이터나 페이지 콘텐츠로 넣는 것은 지양해야합니다.

 

이제 어떤 데이터들을 넣고, 어떤 데이터들을 넣지 말아야 할지 알겠네요.

다음은 Next.js에서 직접 적용해 볼 차례입니다.

 

 

Next.js에서 적용하기

아래 내용은 App router 방식을 기준으로 하며,
Next.js의 모든 메타데이터 생성 함수는 서버 컴포넌트에서만 정상적으로 작동합니다. 

 

Next.js에서는 컴포넌트에서 metadata라는 이름의 변수를 선언하여 메타데이터를 설정할 수 있습니다. 

 

// layout.tsx
import { Metadata } from 'next';

export const metadata: Metadata = {
  title: '..'
  description: '..'
};

 

metadata 변수는 next에 선언되어있는 Metadata 라는 타입을 가지며, 해당 타입이 선언된 d.ts 파일에 가보면 자세한 설명과 함께 용법을 제공합니다. 공식 문서의 가이드 없이 타입 선언만 참고해도 충분할 정도로 상세하게 안내하고 있습니다.

 

metadata-interface.d.ts

 

 

모든 속성을 다 확인하기엔 너무 많습니다.

우리는 주로 쓰이는 메타데이터들을 위주로 알아보겠습니다.

 

 

 

기본 속성

export const metadata: Metadata = {
  title: {
    template: '%s | 유세지의 식물원',
    default: '유세지의 식물원',
    absolute: '빈 페이지 입니다',
  },
  description: '유세지의 식물원입니다',
  authors: [{ name: '유세지', url: 'https://github.com/usageness' }],
}

 

Next.js의 title은 string과 template 객체 두 가지 타입을 받을 수 있습니다.

 

string의 경우 입력한 문자열 그대로 표시되지만, template 객체는 %s를 이용해서 제목을 템플릿 문자열로 만듭니다. 이 경우 하위 페이지에서 title에 string을 입력하면 템플릿의 %s 부분에 입력한 문자열이 들어가게 됩니다.

 

// 하위 page.tsx

export const metadata: Metadata = {
  title: 'About',
}

// <title>About | 유세지의 식물원</title>

 

template 객체를 사용할 경우 default가 반드시 함께 선언되어 있어야합니다. default는 하위 페이지에 title이 선언되지 않았을 경우 적용될 fallback title의 역할을 합니다.

 

absolute는 상위 레이아웃의 템플릿을 무시하고 title을 적용시킬 수 있습니다.

독립적인 페이지가 나와야 할 경우처럼 특수한 상황에 사용하면 좋을 것 같네요.

 

단, 템플릿 객체는 하위 페이지들에만 적용되고, 같은 계층에는 적용되지 않는다는 점을 주의해야합니다. 같은 이유로 page.tsx에서도 template 객체가 적용되지 않습니다. (하위 페이지가 없기 때문입니다)

 

 

description의 경우 string 타입을 받고, 해당 페이지에 대한 설명이 들어갑니다.

위에서 살펴본대로 페이지의 내용을 상세하게 적어주시면 됩니다.

 

authors는 객체 형식으로 name과 url을 함께 적어도 되고, name만 적어도 됩니다.

페이지의 작성자 이름을 넣어주시면 되겠습니다.

 

 

 

openGraph

export const metadata: Metadata = {
  openGraph: {
    title: '유세지의 식물원',
    description: '유세지의 식물원입니다',
    url: 'https://blog-usageness.vercel.app',
    siteName: '유세지의 식물원',
    images: [
      {
        url: 'https://user-images.githubusercontent.com/28296575/198838771-84438140-d95a-4899-b5bc-35cbaa92184a.png',
        width: 800,
        height: 600,
      },
      {
        url: 'https://user-images.githubusercontent.com/28296575/198838771-84438140-d95a-4899-b5bc-35cbaa92184a.png',
        width: 1800,
        height: 1600,
        alt: '유세지의 식물원',
      },
    ],
    locale: 'ko_KR',
    type: 'website',
  },
};

 

facebook과 같은 SNS 공유를 위한 openGraph 속성입니다.

 

title, description, url, siteName 등 기존에 있던 속성들에 더하여 이미지가 추가되었습니다. 공유되는 플랫폼에 따라 적절한 사이즈의 이미지를 사용할 수 있도록 다양한 크기의 이미지를 설정해주시면 좋습니다.

 

 

 

twitter

export const metadata: Metadata = {
  twitter: {
    card: 'summary_large_image',
    title: content.title,
    description: content.subTitle,
    creator: '@dev_usage',
    images: [
      'https://user-images.githubusercontent.com/28296575/198838771-84438140-d95a-4899-b5bc-35cbaa92184a.png',
    ],
  },
}

 

openGraph와 마찬가지로, 현재는 이름이 X로 바뀐 Twitter에서 사용되는 메타데이터입니다.

 

트위터의 경우 카드뷰 형식으로 데이터가 표시되는데, summary, summary_large_image, app, player 등의 속성을 가질 수 있습니다. 주로 summary나 summary_large_image가 많이 사용됩니다.

 

한 가지 특이한 점은 본인의 트위터 아이디를 적는 속성이 있다는 점인데, site, creator 한 곳에 넣어주시면 됩니다.

 

 

 

other

종종 커스텀 메타데이터를 적용해야하는 경우가 있습니다.

예시로 구글의 서치 콘솔을 이용하기 위해서는, 메타태그에 아래 속성을 추가해야합니다.

 

<meta name="google-site-verification" content="1234567890abcdefghijklmn">

 

Next.js가 이것까지 지원해주지는 않지만, other 키워드를 통해 이러한 커스텀 메타데이터들을 넣을 수 있습니다.

 

export const metadata: Metadata = {
  other: {
    'google-site-verification': '1234567890abcdefghijklmn',
  },
};

 

 

 

 

마치며

오늘은 Next.js에서 메타데이터들을 적용하는 방법을 알아보았습니다. 메타데이터 외에도 Next.js에서 지원하는, SEO를 향상시키기 위한 방법들이 더 남아있습니다. 나머지는 다음 시간에 마저 다뤄보도록 하겠습니다.

 

감사합니다.

 

 

 

참고 문서

반응형

댓글