Nextjs App Directory SEO
2024.04.09
Next 13 버전 이후에 도입된 App directory에서 SSR과 SSG를 구성하는 방식이 변경되면서 웹 사이트의 SEO을 동적으로 구성하는 방식들도 변경되었다.
최신 Nextjs 버전에서 SEO를 구성하는 방법들은 다음과 같다.
meta tag
메타 태그는 웹 페이지의 정보를 정의하는 태그로, 웹 페이지의 제목, 설명, 키워드, 작성자, 최종 수정일 등의 정보를 정의할 수 있다.
이러한 정보들로 검색엔진이 웹 페이지의 정보를 분석하고, 사용자에게 보여줄 때에도 웹 페이지의 정보를 표시할 수 있다.
Nextjs에서 meta tag를 설정하려면 layout.tsx
파일에 다음과 같이 정의 할 수 있다.
import { Metadata } from "next";
export const metadata:Metadata = {
title: 'title',
description: 'description',
keywords: ['meta','tag'],
openGraph: {
title: 'Next.js',
description: 'Description',
type: 'article',
publishedTime: '2024-01-01T00:00:00.000Z',
authors: ['byeonmgin']
},
}
아래와 같이 title template을 사용하면 페이지별로 동적으로 title을 지정할 수 있다.
export const metadata: Metadata = {
title: {
default: 'byeongmin.dev',
template: '%s | byeongmin.dev',
},
}
export const metadata: Metadata = {
title: 'Nextjs'
}
이렇게 지정하면 해당 post 페이지의 title은 Nextjs | byeongmin.dev
로 설정된다.
이러한 기능을 활용해서 Nextjs 동적 라우팅으로 생성하는 SSG같은 페이지에서 generateMetadata
함수를 사용하여 동적으로 페이지별로 해당 페이지에 대한 메타 태그를 생성할 수 있다.
export async function generateMetadata({
params,
}: {
params: { slug: string | string[] };
}) {
const allPosts = await getAllFrontmatter("posts");
// 생략 : 해당 페이지에대한 post 정보를 가져온다.
const metadata: Metadata = {
title: post?.title,
description: post?.description,
// 생략
};
return metadata;
}
적용된 메타 태그를 보면 아래와 같이 모든 페이지 별로 동적으로 메타 태그를 생성 된것을 볼 수 있다.
robots.txt
웹 사이트 내의 컨텐츠에 대해 크롤러의 접근 제어에 대한 내용을 정의하고sitemap을 크롤러에게 알려주는 역할을 한다.
기본적으로 모든 사이트의 루트 경로 + /robots.txt 경로에 위치한다. 이 사이트의 https://www.byeongmin.dev/robots.txt 에 접속해도 다음과 같은 내용을 확인할 수 있다.
Nextjs에서 /app/robots.ts
경로로 아래와 같이 robots.txt 파일을 생성할 수 있다.
export default function robots() {
return {
rules: [
{
userAgent: "*",
allow: ["/"],
},
],
sitemap: "https://www.byeongmin.dev/sitemap.xml",
host: "https://www.byeongmin.dev",
};
}
sitemap.xml
sitemap.xml
는 해당 사이트의 모든 URL을 XML 형식으로 나열하여, 컨텐츠들의 업데이트 시점이나 빈도등을 담아서 웹 사이트의 페이지 구조를 크롤러에게 알려준다.
sitemap.xml
파일 역시 기본적으로 사이트의 루트 경로 + /sitemap.xml 경로에 위치한다.
이 사아트의 https://www.byeongmin.dev/sitemap.xml 에 접속해도 다음과 같은 내용을 확인할 수 있다.
Nextjs에서 /app/sitemap.ts
경로로 아래와 같이 sitemap.xml 파일을 생성할 수 있다.
import { MetadataRoute } from 'next'
export default function sitemap(): MetadataRoute.Sitemap {
return [
{
url: 'https://acme.com',
lastModified: new Date(),
changeFrequency: 'yearly',
priority: 1,
},
{
url: 'https://acme.com/about',
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.8,
},
{
url: 'https://acme.com/blog',
lastModified: new Date(),
changeFrequency: 'weekly',
priority: 0.5,
},
]
}
이 블로그와 같이 SSG페이지를 생성하는 경우에는 다음과 같이 sitemap.xml
파일을 생성할 수 있다.
import { getAllFrontmatter } from "@/lib";
import { SITE_URL } from "@/utils";
import { MetadataRoute } from "next";
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const sitemap = [
{
url: SITE_URL,
lastModified: new Date(),
changeFrequency: "weekly",
priority: 1,
},
];
const posts = await getAllFrontmatter("posts");
posts.map((post) => {
sitemap.push({
url: `${SITE_URL}/post/${post.slug}`,
lastModified: new Date(post.date),
changeFrequency: "yearly" as const,
priority: 0.8,
});
});
return sitemap as MetadataRoute.Sitemap;
}
기본적으로 사이트 정보를 sitemap에 담고 getAllFrontmatter함수를 사용하여 SSG로 생성하는 페에지의 정보를 가져와서 동적으로 sitemap을 생성할 수 있다.
이렇게 하면 build시에 sitemap을 생성한다.
이렇게 생성된 sitemap.xml을 검색엔진에 제출하면 검색엔진이 크롤링과 색인 생성을 하여 변경 사항을 자동으로 반영할 수 있다.
-
구글에 제출된 sitemap.xml
menifest.json
PWA를 구성할 때 사용하는 파일로, 웹 앱의 정보를 담고 있는 파일이다. 웹 앱을 다운 받았을때 아이콘, 이름, 시작 URL, 테마 색상 등을 설정할 수 있다.
nextjs에서 /app/manifest.ts
경로로 아래와 같이 menifest.json 파일을 생성할 수 있다.
import { MetadataRoute } from 'next'
export default function manifest(): MetadataRoute.Manifest {
return {
name: 'Next.js App',
short_name: 'Next.js App',
description: 'Next.js App',
start_url: '/',
display: 'standalone',
background_color: '#ffffff',
theme_color: '#ffffff',
icons: [
{
src: '/favicon.ico',
sizes: 'any',
type: 'image/x-icon',
},
],
}
}
SEO 검사하기
크롬 개발자 도구에서 Lighthouse를 사용하여 SEO를 검사할 수 있다.
위에 해당 하는 내용들을 모두 적용했다면, SEO부분에서 쉽게 통과할 수 있다.