Gatsby와 SEO
Gatsby는 정적 사이트 생성과 동적 서버 사이드 렌더링을 결합해 SEO를 최적화하는 데 유리한 플랫폼이다. 아래는 Gatsby의 SEO 관련 주요 특징이다.
- 정적 사이트 생성(Static Site Generation, SSG): 정적 사이트를 생성하므로, 모든 페이지의 HTML이 미리 생성된다. 이는 검색 엔진 크롤러가 콘텐츠를 쉽게 찾고 인덱싱할 수 있도록 한다.
- 서버사이드 렌더링(Server-Side Rendering, SSR) 지원: 동적 콘텐츠에 대한 서버사이드 렌더링을 지원한다. 이를 통해 초기 로딩 속도를 개선하고, 소셜 미디어 미리보기와 같은 기능을 구현할 수 있다.
- 예상 로딩(Prefetching): 링크가 마우스를 올리거나 포커스를 받았을 때 미리 데이터를 가져와 로딩 시간을 줄이는 예상 로딩을 지원한다. 이는 사용자 경험을 향상시키고 SEO에도 도움을 준다.
- 자동 메타데이터 생성: 페이지 제목, 설명, 이미지 등의 메타데이터를 자동으로 생성할 수 있는 플러그인을 제공한다. 이를 통해 소셜 미디어 공유나 검색 결과에서 눈에 띄도록 만들 수 있다.
- 캐싱과 최적화: 자동으로 정적 파일을 생성하고 최적화하여 빠른 페이지 로딩을 가능하게 한다. 또한 이미지 최적화, 코드 스플리팅 등의 기능을 제공하여 성능을 개선한다.
SEO 컴포넌트 활용
Gatsby에서 메타데이터를 원하는 대로 바꾸기 위해서는 SEO 컴포넌트를 따로 만들고, 사용을 원하는 컴포넌트에서 props로 해당 정보를 전달하는 방식을 쓰면 된다.
사이트 이름이나 썸네일 이미지 크기, 지역 정보(og:title, og:image:width, og:image:height, og:locale)와 같은 공통 사항은 SEO 컴포넌트에 고정 데이터로 설정해두고, 각각의 페이지 위치에 따라 변경이 필요한 데이터는 특정 변수로 지정한다. 한편 이 코드에서 쓰인 react-helmet은 클라이언트에서 손쉽게 메타데이터를 바꿀 수 있도록 도와주는 핵심 라이브러리이다. SEO를 위해 서버 사이드 렌더링 방식을 사용할 때 필요하다.
npm i react-helmet
import React from "react";
import { Helmet } from "react-helmet";
// ...
const SEO = ({ title, ogTitle, ogType, ogUrl, ogText }: SEOProps) => {
return (
<Helmet
title={title}
meta={[
{
property: `og:site_name`,
content: "일상연습",
},
{
property: `og:title`,
content: ogTitle,
},
{
property: `og:type`,
content: ogType,
},
{
property: `og:url`,
content: ogUrl,
},
{
property: `og:image`,
content: "https://i.ibb.co/CB51dS6/img2321.png",
},
{
property: `og:image:width`,
content: "672",
},
{
property: `og:image:height`,
content: "672",
},
{
property: `og:image:type`,
content: "image/png",
},
{
property: `og:description`,
content: ogText,
},
{
property: `og:locale`,
content: "ko_kr",
},
]}
/>
);
};
export default SEO;
다음 코드는 포스트 컴포넌트에서 SEO 컴포넌트에 props로 데이터를 전달해 페이지에 맞는 메타데이터를 만들어내는 모습을 보여준다. 페이지의 title과 description, url에 해당하는 메타데이터를 frontmatter 데이터를 활용해 입력했다.
export default function BlogPostTemplate({ data }: BlogPostTemplateProps) {
// ...
return (
<React.Fragment>
<SEO
title={`${frontmatter.title} — 일상연습`}
ogTitle={`${frontmatter.title} — 일상연습`}
ogType={"article"}
ogUrl={"https://14461.gatsbyjs.io/posts" + frontmatter.slug}
ogText={frontmatter.description}
/>
// ...
</React.Fragment>
);
}
export const pageQuery = graphql`
query ($id: String!) {
markdownRemark(id: { eq: $id }) {
html
frontmatter {
// ...
slug
title
description
}
}
allMarkdownRemark {
edges {
node {
id
frontmatter {
title
page
slug
}
}
}
}
}
`;
반응형