ACT3の自社サイトを、WordPressからAstro 5による静的サイトへ移行しました。
今回の移行では、既存の記事、問い合わせフォーム、サイト内検索、旧URLを維持しながら、通常のページ表示を静的ファイルの配信へ切り替えています。
本記事では、WordPressの記事をMarkdownへ変換した方法、フォーム処理をPHPとして残した理由、本番デプロイ時に発生したPagefindと.htaccessの問題を記録します。
移行前に整理した要件
移行前のサイトでは、WordPressで記事や固定ページを管理し、独自PHPによる問い合わせフォームを運用していました。
静的サイトへ移行する場合も、HTMLを生成できれば完了というわけではありません。既存サイトの機能やURLを確認し、移行後にどの仕組みで置き換えるかを決める必要があります。
今回は、次の要件を移行対象としました。
- 記事とお知らせの既存URLを維持する
- WordPress内の記事をMarkdownへ移行する
- 問い合わせフォームの検証・スパム対策を維持する
- データベースを使わずにサイト内検索を提供する
- Xserver上の既存ディレクトリ構成を踏まえて公開する
Astroは、静的HTMLの生成、Markdownコンテンツの管理、既存のSass・JavaScript資産の移植に対応しやすかったため採用しました。
移行プロジェクトの流れ
今回の移行は、単なるHTMLのコピーではありません。既存のwebpack・Sass構成、WordPressに入っていた記事データ、問い合わせフォームのセキュリティロジック、サイト内検索などを整理しながら、Astro上で組み直していきました。
Phase 1: Astro 5の基盤構築
まず、既存プロジェクト内の app/astro/ に独立したAstro 5プロジェクトを作成しました。その後、構成を整理し、現在は app/ 直下をAstroプロジェクトとして管理しています。
既存のSass資産も一部引き継ぎつつ、非推奨になっていた関数の整理も進めています。たとえば darken() のような古い関数は color.adjust() へ置き換え、今後のビルドでも警告が出にくい状態に整えました(あわせて @use "sass:color"; を宣言しています)。
Phase 2: 共通UIのコンポーネント化
ヘッダー、フッター、モバイルメニュー、CTAといった共通UIを、Astroコンポーネントへ分解しました。
また、WordPress側で管理していた「よくあるご質問」「相談の流れ」などの可変データは、Astro内で扱いやすいデータ構造に整理し直しています。これにより、HTMLをベタ書きするのではなく、再利用しやすい形でページを組み立てられるようになりました。
Phase 3: WordPress記事のMarkdown化
WordPressの wp_posts テーブルをSQLダンプから取り出し、Node.js製の変換ツールでMarkdownへ変換しました。
HTMLからMarkdownへの変換にはTurndownを使用しています。Gutenberg由来のHTMLブロックもそのまま移すのではなく、可能な範囲で読みやすいMarkdownへ整え、Frontmatter付きの記事データとしてAstroのContent Collectionsで扱えるようにしました。記事コンテンツをGitで管理できるようになり、変更履歴や差分の確認もしやすくなっています。
Phase 4: Pagefindによる静的サイト内検索
静的化するとWordPressの検索機能は使えなくなるため、サイト内検索にはPagefind 1.5.2を採用しました。
Pagefindは、ビルド済みのHTMLをもとに検索インデックスを生成し、クライアントサイドで高速に検索できる仕組みです。WP_Query のようにサーバー側で検索処理を走らせるのではなく、静的ファイルとして生成されたインデックスをブラウザ側で読み込んで検索します。おかげで、データベースなしでもサイト内検索を維持できました。
Phase 5: フォーム処理の移植
静的サイト化しても、問い合わせフォームは必要です。
今回は、フォーム画面そのものはAstroで静的に生成し、送信処理だけをサーバー上の独立したPHP process.php に切り出しました。既存フォームで使用していた以下の検証・スパム対策も移植しています。
- CSRFトークンの確認
- 送信時間の制限によるスパム対策
- 送信頻度の制限
- Honeypot
- Google reCAPTCHA v3
- 入力値の検証
- メール送信処理
完全な静的サイトではありませんが、WordPress本体を動かさず、フォーム処理だけを最小限のPHPに分離する構成に落ち着きました。
本番デプロイでハマったこと
ローカルやテスト環境では問題なく動いていても、本番サーバーに配置するとサーバー設定や既存の.htaccessの影響で、想定外のトラブルが出てきます。
Pagefind検索時に invalid gzip data が発生する
本番で検索機能を確認したところ、ブラウザのコンソールに次のエラーが表示されました。
Failed to load the Pagefind WASM: Error: invalid gzip data
今回の環境では、Pagefindが生成する .pf_meta、.pf_index、.pf_fragment、.pagefind といったファイルに対するサーバー側のエンコーディング設定が、Pagefindの処理と競合していました。
Pagefind関連ファイルは、Pagefind自身が圧縮・解凍を管理しています。Pagefindの公式ドキュメントでも、サーバー側のgzip対応は不要とされています。今回のエラーは、サーバー側の設定を調整し、Pagefind関連ファイルに余分なエンコーディング情報が付かないようにすることで解消しました。
今回のエックスサーバー環境では、.htaccess に以下の設定を追加することで解決しました。
<IfModule mod_mime.c>
RemoveEncoding .pf_meta
RemoveEncoding .pf_index
RemoveEncoding .pf_fragment
RemoveEncoding .pagefind
RemoveType .pf_meta .pf_index .pf_fragment .pagefind
AddType application/octet-stream .pf_meta .pf_index .pf_fragment .pagefind
</IfModule>
静的サイトはPHPやDBがない分シンプルですが、サーバー側のMIMEタイプやエンコーディング設定の影響はしっかり受けます。とくに、既存サイトの設定を引き継ぐ場合は注意が必要です。
末尾スラッシュのURLで404になる
もう一つハマったのが、記事ページのURLです。
たとえば、次のURLは表示できました。
/insights/4294/index.html
ところが、本来アクセスさせたい次のURLは404になってしまいます。
/insights/4294/
調べてみると、親ディレクトリ側の.htaccessに、旧WordPress用の内部リライトが残っていました。
RewriteRule ^insights/([0-9]+)/?$ /insights/post.php?post_id=$1 [QSA,L]
このルールのせいで、実在するAstroの静的ディレクトリではなく、存在しない post.php へ内部的にリライトされていたわけです。旧WordPress用のリライトルールを削除し、Astroが生成した実体のHTMLへ直接アクセスできるようにすることで解決しました。
WordPressから静的サイトへ移行する際は、ファイルを置き換えるだけでは足りません。上位ディレクトリの.htaccess、旧URLのリダイレクト、内部リライト、キャッシュ設定まで、ひととおり確認しておく必要があります。
移行後も残る動的処理と保守対象
通常のページは静的ファイルとして配信する構成へ変更しましたが、サイト全体が静的ファイルだけで完結しているわけではありません。
問い合わせフォームでは、引き続きPHP、セッション、メール送信処理を使用しています。フォームの設定ファイルやメールテンプレートもサーバー上に配置するため、アクセス制限とデプロイ対象の確認が必要です。
サイト内検索はPagefindが生成したファイルをブラウザで読み込みます。そのためデータベースは使用しませんが、記事を追加・修正した際は、Astroのビルド後にPagefindのインデックスも再生成する必要があります。
また、Astro、Pagefind、Sass、npmパッケージ、PHP、サーバー設定は継続して保守対象になります。WordPress固有の更新作業はなくなりましたが、移行後の構成に合わせた更新・検証・バックアップは必要です。
Xserver上で静的サイトへ移行する際の確認事項
今回の移行では、Astro側の実装よりも、既存サイトの設定を引き継ぐ段階で問題が発生しました。
とくに、Xserver上でWordPressから静的サイトへ切り替える場合は、公開前に次の項目を確認する必要があります。
- 親ディレクトリを含む
.htaccessのリライトルール - 旧URLから新しいURLへのリダイレクト
- ディレクトリURLと
index.htmlの扱い - Pagefind関連ファイルのMIMEタイプとエンコーディング
- PHPフォーム、設定ファイル、メールテンプレートの配置先
- デプロイ対象に必要なPHPや
.htaccessが含まれているか - 404ページが正しいHTTPステータスで返るか
静的サイトへ移行しても、サーバー設定やフォーム処理まで不要になるとは限りません。既存のURLや機能を維持する場合は、WordPress側の実装だけでなく、公開ディレクトリの外側にある設定も含めて調査することが重要です。