본 글에서는 SEO를 위한 방법들을 소개하고, 이를 Next.js를 사용하고 있는 프로젝트에 어떻게 적용했는지 소개한다.
Google의 SEO 기본 가이드에 따르면 다음과 같은 부분들을 개선할 수 있다.
웹사이트에서 구글이나 네이버와 같은 검색 엔진에 색인할 모든 페이지를 나열한 XML 파일
Google의 SEO 기본 가이드에 따르면…
내 사이트가 Google에서 검색되도록 하기 위한 첫 번째 단계는 Google이 사이트를 발견할 수 있도록 하는 것입니다. 이때는 사이트맵을 제출하는 것이 가장 좋습니다. 사이트맵은 사이트에 있는 파일로서 새 페이지나 변경된 페이지가 있을 때 이를 검색엔진에 알려 줍니다.
🤔 Knoticle 프로젝트의 사이트맵을 생성하려면
Knoticle 프로젝트에서는 Next.js를 사용하고 있는데, Next.js의 SSR과 next-sitemap 라이브러리를 통해 동적으로 사이트맵을 생성할 수 있다.
knoticle.app/viewer/{책 id}/{글 id}
와 같이 구성되어 있다.{책 id}/{글 id}
를 DB에서 일정 시간 간격으로 받아와서 sitemap 을 생성해야 한다. → next-sitemap
이라는 라이브러리 사용(링크)책 id
와 글 id
가 필요하다.scraps
테이블에 책 id
와 글 id
가 저장되어 있다. → 그 중 글이 원본인 아이템(즉, 원본 책 id
와 글 id
의 조합)만 받아오도록 했다. 검색엔진에 원본 글만 잡히는 것이 맞다고 생각했다.받아온 정보들로 페이지마다 field를 생성한다.
field는 다음과 같은 형태로 구성되어 있는데,
loc: `${process.env.NEXT_PUBLIC_CLIENT_URL}/viewer/${scrap.book_id}/${scrap.article_id}`,
changefreq: 'daily',
priority: '1.0',
lastmod,
→ 하지만 Google 검색 센터에 따르면, Google에서는 <priority>
및 <changefreq>
값을 무시한다고 한다.
생성된 fields로 sitemap.xml을 구성한다.
코드는 다음과 같다.
// pages/sitemap.xml.tsx
import { GetServerSidePropsContext } from 'next';
import { getServerSideSitemap } from 'next-sitemap';
import { getScrapsApi } from '@apis/scrapApi';
export default function SiteMapXML() {
return <></>;
}
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
const scraps = await getScrapsApi();
const lastmod = new Date().toISOString();
const defaultFields = [
{
loc: `${process.env.NEXT_PUBLIC_CLIENT_URL}`,
changefreq: 'daily',
priority: '1.0',
lastmod,
},
];
const scrapFields = scraps.map((scrap: { book_id: number; article_id: number }) => ({
loc: `${process.env.NEXT_PUBLIC_CLIENT_URL}/viewer/${scrap.book_id}/${scrap.article_id}`,
changefreq: 'daily',
priority: '1.0',
lastmod,
}));
const fields = [...defaultFields, ...scrapFields];
return getServerSideSitemap(context, fields);
};
검색엔진 크롤러가 사이트맵을 찾을 수 있도록 검색엔진별로 제출하는 것이 필요하다.
<meta>
태그는 해당 문서에 대한 정보인 메타데이터(metadata)를 정의할 때 사용한다 : <base>
, <link>
, <script>
, <style>
, <title>
요소와 같은 다른 메타데이터 관련 요소들이 나타낼 수 없는 다양한 종류의 메타데이터를 제공할 때 사용되며, 이렇게 제공된 정보는 브라우저나 검색 엔진, 다른 웹 서비스에서 사용하게 된다메타 설명 태그는 중요합니다. Google에서 설명 메타 태그를 Google 검색결과에서 페이지의 스니펫으로 사용할 수 있기 때문입니다.
<title>
태그와 관련되어 있고, 그 아래 설명은 <meta name=”description”>
과 관련되어 있다.구글 공식 문서에 따르면, 구글에서 인식하는 메타 태그에는 다음이 있다.
<meta name="description" content="A description of the page" />
: 간단한 페이지 설명<meta name="viewport" content="...">
: 휴대기기에서 페이지를 렌더링하는 방법을 브라우저에 알리는 태그. 이 태그를 사용하면 페이지가 모바일 친화적이라는 사실을 Google에 알릴 수 있다.<meta http-equiv="Content-Type" content="...; charset=..." />
<meta charset="..." >
: 페이지의 콘텐츠 유형과 문자 집합을 정의하는 태그. 가능한 경우 Unicode/UTF-8을 사용하는 것이 좋다.따라서,
<title>
및 <meta name=”description”>
태그를 페이지마다 다르게 생성하자.open graph
에 관련된 메타 태그도 페이지마다 다르게 지정해주자.getServerSideProps
로 article 데이터 받아오기
export const getServerSideProps: GetServerSideProps = async (context) => {
const [bookId, articleId] = context.query.data as string[];
const article = await getArticleApi(articleId);
return { props: { article } };
};
getServerSideProps
는 서버에서 동작하는 코드이므로, 함수 내부에서 next/router를 사용할 수가 없다.import Head from 'next/head';
interface ViewerHeadProps {
articleTitle: string;
articleContent: string;
}
export default function ViewerHead({ articleTitle, articleContent }: ViewerHeadProps) {
return (
<Head>
<title>{articleTitle}</title>
<meta name="description" content={articleContent.slice(0, 150)} />
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<meta property="og:title" content={articleTitle} />
<meta property="og:description" content={articleContent.slice(0, 150)} />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://www.knoticle.app" />
<meta property="og:image" content="https://kr.object.ncloudstorage.com/j027/knoticle.png" />
</Head>
);
}
아래와 같이 knoticle 서비스의 글 링크를 노션에 복사해서 붙여넣으면 다음과 같이 표현된다.
이전
적용 후
참고 자료
사이트맵이란 무엇인가요? | Google 검색 센터 | 문서 | Google Developers
The Importance of The XML Sitemap Priority and Changefreq Tags
사이트맵 만들기부터 제출하기: 쉬운 단계별 가이드 | TBWA 데이터랩
Data Fetching: getServerSideProps | Next.js
Robots.txt Sitemap: Add Your Sitemap To Your Robots.txt File
What is Open Graph and how can I use it for my website?