記事一覧に戻る

ポートフォリオサイトをNext.jsに移行しました

2026-04-062 min read更新履歴
ポートフォリオリリースノートNext.jsSEO

概要

ポートフォリオサイトの技術基盤を React + Vite(SPA)から Next.js(App Router)に移行しました。 主な目的はSEO対策で、ブログ記事が検索エンジンに個別にインデックスされるようになりました。

なぜ移行したのか

これまでのサイトはSPA(シングルページアプリケーション)として構築されていたため、ブラウザがJavaScriptを実行しないとコンテンツが表示されませんでした。検索エンジンのクローラーにとってはほぼ空のページに見えてしまい、ブログ記事が検索結果に載りにくい状態でした。

Next.jsのSSG(Static Site Generation)に移行することで、各ページが事前にHTMLとして生成されるようになり、クローラーがJSなしでもコンテンツを取得できるようになりました。

変更内容

SEO対策

  • 各ページに適切な <title> タグと <meta name="description"> を設定
  • OGPタグ(og:title, og:description, og:type)を全ページに追加
  • ブログ記事には Article スキーマの構造化データ(JSON-LD)を埋め込み
  • トップページには WebSite スキーマの構造化データを追加
  • sitemap.xmlrobots.txt を自動生成

ブログ記事のSSG

  • 各ブログ記事が /blog/{slug} で個別のHTMLファイルとして生成されるように
  • URLを直接指定してもページが表示される(SPAのフォールバック設定が不要に)
  • 記事ごとのmetaタグが動的に生成され、SNSシェア時にも適切なプレビューが表示される

その他の改善

  • lang 属性を "jp"(誤り)から "ja" に修正
  • テーマ切替時のフラッシュ(一瞬デフォルトテーマが表示される現象)を防止するインラインスクリプトを追加

技術的な話

  • Next.js の output: 'export' モード(Static Export)を採用し、既存のVPSデプロイ(rsync)をそのまま維持。Node.jsサーバーの常時稼働は不要
  • ブログ記事の読み込みを Vite の import.meta.glob(クライアントサイドバンドル)から fs.readFileSync(ビルド時のサーバーサイド読み込み)に変更
  • Server Component と Client Component を適切に分離。テーマ切替やMarkdownレンダリングなどブラウザAPIを使う部分のみ Client Component に
  • CDパイプライン(GitHub Actions)のビルドコマンドとデプロイ対象ディレクトリを dist/ から out/ に変更