SEO와 Metadata (with Next.js)
안녕하세요. 이번 포스팅에서는 SEO(Search Engine Optimization)와 Metadata에 대해 알아보고 이를 Next.js 환경에서 어떻게 적용할 수 있는지 블로그 프로젝트를 작업한 예제와 함께 살펴보겠습니다.
SEO를 위한 전략들
먼저 SEO에 대해 이해하고 SEO가 필요한 이유에 대해 알 필요가 있습니다.
열심히 사이드 프로젝트를 만들어 배포까지 마무리했다고 생각해 봅시다. 사용자들은 우리의 사이트에 어떻게 접근할 수 있을까요? 대부분의 경우 검색 엔진을 통해 노출된 결과로 사이트에 접속하게 됩니다. 그리고 이 때, 대다수의 사용자들은 검색엔진의 상위에 노출된 사이트를 우선적으로 열람하게 됩니다. 즉 우리의 사이트가 더 많은 사용자들에게 노출되길 원한다면 검색엔진 검색 결과의 상위에 노출되도록 해야하고 이러한 과정을 SEO(Search Engine Optimization)라고 합니다. 이러한 검색엔진 최적화는 기존 콘텐츠를 활용해 무료 트래픽을 얻을 수 있는 매력적인 마케팅 전략 중 하나입니다.
그렇다면 개발자의 관점에서는 검색 엔진 최적화를 위해 어떤 작업을 할 수 있을까요?
먼저 SSR(Server Side Rendering)을 고려할 수 있습니다. SSR은 서버에서 렌더링된 HTML을 가져오므로 검색 엔진이 콘텐츠를 완전히 이해할 수 있어 초기 렌더링 시 비어있는 HTML을 가져오는 CSR 대비 SEO에 유리합니다. 아래의 예시에서 알아볼 블로그 프로젝트는 Nextjs로 개발하여 처음부터 SSR로 제작하였습니다. 하지만 이와 달리 초기에 SSR로 설계되어 있지 않다면 CSR로 되어있는 프로젝트를 SSR로 리팩토링 하는 것은 리소스가 많이 드는 작업이 될 수 있습니다.
그 다음으로 고려할 수 있는 것은 Metadata입니다. Metadata는 검색엔진 최적화를 위한 중요한 전략 중 하나입니다. Metadata는 검색엔진이 페이지를 이해하고 인덱싱하는데 도움이 되는 정보를 제공하고 검색엔진은 이를 분석하여 페이지의 주제, 내용, 키워드 등을 파악하고 검색 쿼리와 일치하는 페이지를 사용자에게 제공합니다. 즉 사용자는 Metadata를 통해 검색 결과 페이지에서 페이지의 제목과 설명을 통해 페이지의 내용을 미리 알 수 있습니다.
그럼 이제 Metadata를 실제 프로젝트에서 어떻게 적용할 수 있는지 알아봅시다.
Metadata - Meta Tags & Open Graph
메타 태그와 오픈 그래프는 웹 페이지의 메타데이터를 정의하여 웹 브라우저, 검색 엔진, 소셜 미디어 등에 정보를 제공하는데 사용됩니다. 메타태그는 페이지 title, viewport 등 페이지 자체의 정보를 명시하기 위해 사용됩니다. Open Graph 태그는 주로 소셜 미디어에서 페이지를 공유할 때 사용되며 미리보기시 나타나는 페이지의 제목, 설명, 이미지 등을 지정합니다. 이때, 메타 데이터들은 <head>
태그 안에 작성되므로 웹 콘텐츠에는 영향을 미치지 않습니다.
메타 태그(Meta Tags)
메타 태그는 html 문서의 head 섹션에 포함되며, 웹 페이지에 대한 부가 정보를 제공합니다.
아래는 많이 사용되는 메타 태그들입니다.
참고로 keyword
태그의 경우 검색엔진에게 주요 키워드를 알려주는 태그이지만 무분별하게 사용되는 경우가 많아 최근에는 검색엔진이 이를 무시하는 경향이 있다고 합니다.
<meta charset="UTF-8"> <!-- 문서의 문자 인코딩 지정 --> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 모바일 기기에서 화면의 크기와 비율을 제어 --> <title>페이지 제목</title> <!-- 페이지 설명 --> <meta name="description" content="이 페이지는 검색 엔진 최적화 예제입니다."> <!-- 페이지 키워드 --> <meta name="keywords" content="검색 엔진 최적화, SEO, 메타 태그">
Open Graph 및 Twitter Card
오픈 그래프 태그는 주로 소셜 미디어에서 페이지를 공유할 때 사용되며 페이지의 제목, 설명, 이미지 등을 지정합니다. 아래는 대표적으로 사용되는 오픈 그래프 태그들이며 오픈 그래프 프로토콜 사이트에서 더 많은 오픈 그래프 태그들을 확인할 수 있습니다.
<!-- Open Graph 메타 태그 (Facebook, LinkedIn 등에서 공유할 때 사용) --> <meta property="og:title" content="페이지 제목"> <meta property="og:description" content="이 페이지는 검색 엔진 최적화 예제입니다."> <meta property="og:image" content="이미지 URL"> <meta property="og:url" content="현재 페이지 URL"> <meta property="og:type" content="website"> <!-- Twitter Card 메타 태그 (Twitter에서 공유할 때 사용) --> <meta name="twitter:card" content="summary_large_image"> <meta name="twitter:title" content="페이지 제목"> <meta name="twitter:description" content="이 페이지는 검색 엔진 최적화 예제입니다."> <meta name="twitter:image" content="이미지 URL">
참고로 이미지 태그의 이미지는 1200 * 630 사이즈 이상, 8MB 사이즈 이하의 이미지를 권장하고 있습니다.
<meta property="og:image" content="이미지 URL">
Nextjs Layout에서 Metadata 사용하기
그럼 이제 위에서 본 Metadata들을 실제 프로젝트에서 적용해보겠습니다. Next.js에서는 어떻게 Metadata를 지정할 수 있을까요?
물론 페이지마다 <head>
태그 안에 Metadata를 설정할 수도 있겠지만 Next13 이후로 Next.js에서는 layout과 generateMetadata라는 좋은 기능을 제공하고 있습니다. 아래는 이를 사용해 블로그 프로젝트에서 Metadata를 적용해본 예제입니다.
Layout.tsx
는 아래와 같은 원리로 페이지에 적용되며 페이지별로 지정할수도있고 전체 페이지에 적용할 수도 있습니다. 저는 전체 페이지에 적용되도록 코드를 작성했습니다.
return <Layout> <MyPageComponent /> </Layout>
또한 기존에는 <Head>
태그 안에 meta 태그를 만들어 Metadata를 작성했지만 Next13 이후로는 layout.tsx
나 page.tsx
에 Metadata라는 변수를 선언하고 이를 export함으로서 간단하게 정적인 Metadata를 선언할 수 있습니다.
다음은 Layout.tsx
에서 Metadata를 작성한 코드입니다. static한 string을 사용할수도 있고 템플릿을 사용하여 기본값과 페이지 별로 변경되는 값을 지정할수도 있습니다. %s
로 작성된 부분들은 각 페이지별로 선언할 수 있습니다.
export const metadata: Metadata = { metadataBase: new URL('https://yeseul-blog.vercel.app/'), title: { template: `%s | ${blogName}`, default: `${blogName}`, }, description: `%s`, images: `%s`, openGraph: { type: 'website', title: { template: `%s`, default: `${blogName}`, }, }, }
동적인 Metadata를 선언하고 싶다면 page.tsx
에서 generateMetadata
함수를 사용해 동적으로 메타데이터를 선언할 수 있습니다.
generateMetadata
함수는 page에서 받을 수 있는 params
를 받아올 수 있으며 이를 사용해 data fetching을 할 수 있습니다. 단 generateMetadata
함수는 서버 컴포넌트에서만 사용 가능합니다.
아래의 코드에서는 page params
로 받아온 path
를 title
로 선언하고 이를 이용해 데이터를 불러와 오픈그래프 태그에 활용하고 있습니다.
post/[path]/page.tsx
export async function generateMetadata({ params: { path } }: PostDetailProps) { const decodedPath = decodeURIComponent(path) const postingData = await getRawPosts(`blog/${decodedPath}.md`)= const { data: metadata } = matter(postingData as unknown as string) const { title, summary, thumbnail } = metadata return { title: path, openGraph: { title, description: summary, images: [{ url: thumbnail, width: 400, height: 300 }], }, } }
이렇게 설정한 Metadata들은 실제 html에서 아래와 같이 나타납니다.
그렇다면 이러한 Metadata가 실제로 SEO에 어떤 영향을 주었을까요? 이를 정량적인 지표로 알아보기 위해 Metadata 적용 전과 후에 Lighthouse를 통해 SEO 지표 점수를 평가해봤습니다.
위가 SEO 적용 전 아래가 SEO 적용 후입니다. 해당 프로젝트는 SSR로 만들어져 기존에도 SEO 점수가 높았지만 Metadata 적용 후 SEO 점수가 10점이나 오른것을 확인할 수 있습니다. 물론 블로그는 간단한 사이트이므로 다른 거대 사이트와 비교할 수는 없지만 Metadata 적용이 SEO에 큰 영향을 미치는 것을 확인할 수 있습니다.
또한 메타데이터는 소설 미디어에 우리의 콘텐츠를 공유할 때도 더 정확하게 공유할 수 있습니다. 아래는 메타 데이터 적용 전과 후의 카카오톡 미리보기입니다.
메타데이터 적용 전인 왼쪽은 이미지 썸네일도 블로그 홈과는 연관없는 이미지이며 설명 또한 나오지 않아 어떤 컨텐츠인지 알아보기 어렵습니다.(title tag는 적용된 상태입니다.) 메타데이터를 지정한 후인 오른쪽의 경우 지정한 썸네일 이미지와 설명글이 들어가있는 것을 확인할 수 있습니다.
카카오톡을 예시로 가져왔지만 다른 소셜 미디어에서도 비슷하게 적용되었습니다.
(참고로 카카오톡과 같은 실시간 채팅 서비스는 metadata를 그때 그때 가져오는 것이 아니라 캐싱해서 사용하기 때문에 오픈 그래프 태그를 적용해도 변경된 것이 확인되지 않는다면 해당 링크에 들어가 캐시를 무효화 해주어야 합니다.)
마무리
지금까지 SEO를 위한 Metadata 적용방법에 대해 알아보았습니다.
Metadata를 통한 검색엔진 최적화는 검색엔진에게 우리 페이지에 대한 정보를 제공하는 중요한 전략 중 하나입니다. 그러나 현대의 검색엔진은 사람과 유사한 수준의 인식력을 가지고 있으며 페이지를 색인하고 관리하는 성능은 계속해서 고도화되고 있습니다. 즉 SEO에는 양질의 콘텐츠와 웹 페이지의 성능의 비중이 크다는 것을 늘 염두에 두어야 합니다. 마지막으로, SEO는 지속적인 프로세스이며 사용자 행동 변화에 대응하여 지속적으로 최적화해 나가는 것이 필요합니다. 양질의 콘텐츠와 최적화된 페이지로 사용자에게 가치를 제공하고 검색엔진에게도 적절한 정보를 전달해야 합니다.
https://library.gabia.com/contents/domain/4359/ https://yozm.wishket.com/magazine/detail/1540/ https://blog.ab180.co/posts/google-seo-guide-part-one