🧚
Next.js App Router で実践した SEO & Core Web Vitals 改善
はじめに
自分のポートフォリオサイト(Next.js 15 + App Router)を
「名前検索で 1 位表示 & Core Web Vitals オールグリーン」
にするまでに行った 10 の施策をまとめます。
TL;DR
カテゴリ | やったこと | 成果 |
---|---|---|
メタ |
generateMetadata で title/description/keywords を 3 言語動的生成 |
CTR↑ |
構造化データ |
Person & WebSite JSON-LD 追加 |
リッチリザルト候補 |
URL 設計 | セクションを独立ページ化 (/about , /research …) |
クローラビリティ↑ |
Sitemap |
app/sitemap.ts で全言語×全ページ自動生成 |
Index Coverage 100% |
Robots |
/robots.txt 自動生成 |
クロール最適化 |
i18n |
next-intl + サブパス (/ja , /en , /zh ) |
多言語 SEO ベストプラクティス |
画像 |
next/image + priority
|
LCP 改善 |
フォント | Google Fonts display:"swap" & preconnect
|
FOIT 回避 |
コード分割 |
dynamic() で下層ページ遅延ロード |
JS バンドル 25% 削減 |
Analytics | GA4 を <Script strategy="afterInteractive"> で挿入 |
CLS 0 |
generateMetadata
を完全活用
1. title=src/app/[locale]/layout.tsx
export async function generateMetadata({ params }: { params: { locale: string } }): Promise<Metadata> {
const metaByLocale = { ja: {...}, en: {...}, zh: {...} };
const m = metaByLocale[params.locale] ?? metaByLocale.ja;
return {
...m,
openGraph: {
url: "https://ryosh.in",
images: ["https://ryosh.in/logo.png"],
},
twitter: { images: ["https://ryosh.in/logo.png"] },
};
}
-
keywords
は 「指名+肩書+大学名+専門領域」 の組み合わせで作成 - 画像 URL は絶対パスでないと無効になるので注意
2. JSON-LD でリッチリザルトを狙う
title=src/components/StructuredData.tsx
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(getPersonData(locale)) }}
/>
@type:"Person"
に SNS・論文・スキルを盛り込み、
@type:"WebSite"
に SearchAction
を追加してサイト内検索もアピール。
3. ハッシュではなくページとして分割
-
理由: Google は
#about
を別ページとは認識しない -
実装:
src/app/[locale]/about/page.tsx
にAboutSection
を配置 -
Navigation は
next/link
でrouter.push("/ja/about")
4. Sitemap をコードで自動生成
title=src/app/sitemap.ts
const locales = ["ja","en","zh"] as const;
const pages = ["","about","research","skills","projects","gallery"] as const;
export default function sitemap(): MetadataRoute.Sitemap {
return locales.flatMap(locale =>
pages.map(p => ({
url: `https://ryosh.in/${locale}${p&&"/"+p}`,
lastModified: new Date(),
priority: p==="" ? 1 : 0.9,
}))
);
}
5. Core Web Vitals 改善ポイント
指標 | Before | After | 対策 |
---|---|---|---|
LCP | 2.9 s | 1.7 s | 画像 priority + Hero のみ初期ロード |
CLS | 0.12 | 0.00 | GA4 script を遅延読み込み |
JS | 170 kB | 128 kB |
dynamic() でコード分割 |
6. Vercel へのデプロイを自動化
# release ブランチに push → CI
npm run build
vercel deploy --prod --yes
7. 参考リンク
おわりに
指名検索だけなら最低限でも上位表示できますが、
「研究テーマ」「技術スタック」まで拾ってもらうには 構造化データと多言語メタ が効きます。
ポートフォリオをお持ちの方はぜひ試してみてください!
Discussion