【Next.js / App Router】自分がいつも行っているSEO対策TODOリスト
目次
こんにちは!@Ryo54388667です!☺️
普段は都内でエンジニアとして業務をしてます!
主にTypeScriptやNext.jsといった技術を触っています。
今回はApp Routerを利用した時、自分がいつも行っているSEO対策を紹介していきます!
宣伝
TDH(title, description, h1)の設定
#概要
#Titleは、HTMLのtitleタグを指します。ブラウザのタブ名に反映されるだけではなく、クローラーに適切に伝えるためにも重要な要素となっています。ベストプラクティスについては下記のリンクに記載されています。
https://developers.google.com/search/docs/appearance/title-link?hl=ja
続いて、descriotionは、<meta name="description" content=”{ここの内容}”>
を指します。主にページの要約を書きます。
ターゲットとなるキーワードをこちらに盛り込むと良いと言われています。ベストプラクティスについては、下記のリンクを見てください。
https://developers.google.com/search/docs/appearance/snippet?hl=ja
h1についてはページのタイトルにあたるものを設定してください。
実装
#ルートレイアウトでテンプレートを設定します。%s
を利用するとネストしたレイアウトで設定したtitleが差し替えられます。
export const metadata: Metadata = {
title: {
template: `%s | ${SITE_TITLE}`,
default: "Home",
},
description: SITE_DESCRIPTION,
metadataBase: new URL(baseURL)
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
...
);
}
動的にメタ情報を設定する場合はgenerateMetadata
を利用します。
export async function generateMetadata(
{ params }: { params: { blogId: string } },
): Promise<Metadata> {
const blogId = params.blogId
const data = await getBlogById(blogId)
return {
title: data.title,
description: data.description
}
}
詳しくはZennで書きましたので、こちらもご覧ください!
h1については通常どおり、bodyタグ内で記述すればOKです!
Sitemapの作成
#概要
#クローラーに効率的にサイトをクローリングしてもらうために利用します。ベストプラクティスについては下記のリンクを見てください。
https://developers.google.com/search/docs/crawling-indexing/sitemaps/overview?hl=ja
実装
#Next.jsのApp Routerでの実装方法について紹介します。
※ v13.3.0以上
import { MetadataRoute } from "next";
import { baseURL } from "@/config";
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const staticPaths = [
{
url: `${baseURL}/blogs`,
lastModified: new Date()
},
{
url: `${baseURL}/about`,
lastModified: new Date()
}
]
const blogList = await getAllBlogList()
const dynamicPaths = blogList.map((content) => {
return {
url: `${baseURL}/blogs/${content.id}`,
lastModified: content.publishedAt || content.updatedAt
}
})
return [...staticPaths, ...dynamicPaths]
}
構造化データJSON-LDの設定
#概要
#特定のスニペットを記述すると、Googleの検索結果の見え方を工夫できる機能です。例えば、某飲食店評価サイトの検索結果は店名と同時に評価などがGoogleの検索結果に表示されます。特定のスニペットを利用すると、検索結果を工夫することができ、CTRの改善につながることもあります。ベストプラクティスについては下記のリンクを見てください。
https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data?hl=ja
下記のページも一覧になっていてわかりやすいです!
https://www.kabanoki.net/2151/#google_vignette
実装
#import type { BreadcrumbList, BlogPosting ,WithContext } from "schema-dts"
import { baseURL } from "@/config"
type JsonLDProps = {
data: any
}
const JsonLD = ({ data }: JsonLDProps) => {
const breadcrumbJsonLD: WithContext<BreadcrumbList> = {
"@context": "https://schema.org",
"@type": "BreadcrumbList",
itemListElement: [
{
"@type": "ListItem",
position: 1,
name: "Home",
item: `${baseURL}/blogs`
},
{
"@type": "ListItem",
position: 2,
name: data.title,
item: `${baseURL}/blogs/${data.id}`
}
]
}
const blogPostingJsonLD: WithContext<BlogPosting> = {
"@context": "https://schema.org",
"@type": "BlogPosting",
mainEntityOfPage: {
"@type": "WebPage",
"@id": `${baseURL}/blogs/${data.id}`
},
headline: data.title,
datePublished: data.publishedAt || data.updatedAt,
dateModified: data.updatedAt,
keywords: [...data.category.map(({ name }) => name), data.title].join(","),
description: data.description,
image: data.thumbnail?.url,
author: {
"@type": "Person",
name: "xxxxxx",
jobTitle: "Software Engineer",
url: `${baseURL}/about`
},
}
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify([blogPostingJsonLD,{ ...breadcrumbJsonLD }]) }}
/>
)
}
export default JsonLD
Google Analytics
#実装
#Next.jsからサードパーティ用のライブラリが用意されています。こちらを活用するのが良いです!
import { GoogleAnalytics } from "@next/third-parties/google";
import { baseURL, gaId } from "@/config";
export default function Layout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="ja">
<body>
{children}
</body>
<GoogleAnalytics gaId={gaId} />
</html>
);
}
最後に
#最後にTODOリストを掲載しておきます!
- TDH(title, description, h1)の設定
- Sitemapの作成
- 構造化データJSON-LDの設定
- Google Analytics
より良い方法があれば教えてください〜
最後まで読んでいただきありがとうございます!
気ままにつぶやいているので、気軽にフォローをお願いします!🥺