公開したばかりのWordPressサイトをAIと一緒にAstroへ移行してみた【後編】記事のMarkdown化からサイト再構築まで
はじめに
前編では、Astroのインストール、Macの再起動後にnpmが使えなくなったトラブル、そしてWordPressからのデータ取得について書きました。今回は、取得したWordPressのデータを使い、実際にAstroでサイトを構築していきます。
とはいっても、Astroの構文や仕組みを最初から理解していたわけではありません。今回もAIに相談しながら、ひとつずつ進めることにしました。
今回の目標は、WordPressの記事をMarkdownに変換し、既存サイトのデザインをAstroで再現して、公開できる状態に近づけることです。
1. まずAIにサイト全体の構成を考えてもらう
前編で、WordPressからXMLファイルをエクスポートしました。
今回は、そのデータを使ってAstroのサイトを構築します。ただし、ここで注意したいのが、WordPressとAstroではサイトの仕組みが異なることです。WordPressで使用していたテーマやPHPファイルを、そのままAstroにコピーしても動きません。
そこで最初に、AIに以下の情報を渡しました。
- WordPressからエクスポートしたXML
- 現在のサイトのスクリーンショット
- サイトのURL構造
- 移行後も残したい機能
- Astroプロジェクトの現在のファイル構成
AIに依頼する際は、次のような指示が使えます。
AIへの指示文
WordPressで作成したブログをAstroの静的サイトへ移行したいです。
WordPressのXMLファイルと、現在のWebサイトのスクリーンショットを添付します。
以下の条件でAstroのサイト構成を提案してください。
- HTMLとCSSを中心に構築する
- 記事はMarkdownで管理する
- ヘッダーとフッターは共通化する
- 投稿記事と固定ページを表示できるようにする
- カテゴリー別の記事一覧を用意する
- PC・スマートフォンに対応する
- 不要なJavaScriptは追加しない
- 静的HTMLとしてビルドできる構成にする
まず、必要なディレクトリとファイルの構成を説明してください。
既存のAstroプロジェクトを変更する場合は、修正が必要なファイルを明示してください。
ここで、いきなりサイト全体のコードを生成してもらうのではなく、まず構成を確認します。
AIは便利ですが、一度に大量の処理を指示すると、途中で必要な設定が抜けたり、既存コードと矛盾する内容が出てきたりすることがあります。
そのため、設計を確認してから、機能ごとに実装していくことにしました。
2. WordPressの記事をMarkdownへ変換する
次に、記事をMarkdown形式に変換します。
WordPressからエクスポートしたXMLには、記事タイトル、本文、公開日、カテゴリー、タグなどが含まれています。
Astroでは、これらをMarkdownファイルのFrontmatterで管理できます。
例えば、次のような形式です。
---
title: "Astroへの移行記録"
description: "WordPressからAstroへ移行した記録"
pubDate: 2026-11-01
category: "Web制作"
draft: false
---
# Astroへの移行記録
ここから記事本文です。
## Astroを選んだ理由
記事の本文を書きます。
--- で囲まれた部分がFrontmatterです。
title は記事タイトル、pubDate は公開日、category はカテゴリーを表します。
まず1記事だけ変換する
今回は、いきなり全記事を変換するのではなく、まず1記事を試す方法を勧めます。
AIへの指示文は次のとおりです。
WordPressの記事データをAstro用のMarkdownへ変換してください。
以下の条件を守ってください。
- 元の文章を勝手に書き換えない
- 記事タイトル、公開日、カテゴリーを維持する
- 見出し、リスト、リンクを適切なMarkdownにする
- 画像URLを確認する
- WordPress独自のショートコードは勝手に削除しない
- Frontmatterを付ける
- 変換できなかった箇所を報告する
まず1記事だけ変換してください。
1記事を変換したら、必ず元の記事と比較します。
特に見出し、リスト、画像、リンク、コードブロックなどは、意図しない変換が起こっていないか確認します。
大量の記事がある場合は?
記事が数百件ある場合、すべてをAIに1件ずつ変換してもらう方法は非効率です。
その場合は、AIに一括変換プログラムを作成してもらいます。
例えば、次のように依頼します。
WordPressのXMLファイルを読み込み、投稿記事をAstro用のMarkdownへ一括変換するPythonスクリプトを作成してください。
条件は次のとおりです。
- XMLの元ファイルは変更しない
- 1記事につき1つのMarkdownファイルを生成する
- タイトル、公開日、カテゴリー、本文を維持する
- スラッグをファイル名に使用する
- ファイル名の重複を検出する
- 画像URLを一覧化する
- ショートコードやSWELL独自のブロックを検出する
- 変換できなかった部分はログに記録する
- 変換前後の記事数を比較する
- 最初は3記事だけ試験変換する
初心者でも実行できるように、Macのターミナルでの操作方法も説明してください。
この方法なら、記事の数が増えても同じルールで処理できます。
ただし、SWELL独自の装飾やWordPressのブロック構造は、単純なMarkdown変換で完全には再現できません。
変換後に確認する作業は必要です。
3. AstroでMarkdownを読み込めるようにする
Markdownに変換したら、Astroで読み込めるように設定します。
Astroには、Content Collectionsという記事データを管理する仕組みがあります。
今回の構成例は次のとおりです。
src/
├── content.config.ts
├── data/
│ └── blog/
│ ├── first-post.md
│ └── second-post.md
├── layouts/
│ └── MigratedLayout.astro
└── pages/
├── index.astro
└── blog/
└── [slug].astro
※ディレクトリ構成は一例です。Astroのバージョンや既存プロジェクトの構成に合わせて調整してください。
src/content.config.ts に次のような設定を記述します。
import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';
const blog = defineCollection({
loader: glob({
pattern: '**/*.md',
base: './src/data/blog',
}),
schema: z.object({
title: z.string(),
description: z.string().optional(),
pubDate: z.coerce.date(),
category: z.string(),
draft: z.boolean().default(false),
}),
});
export const collections = { blog };
この設定では、記事のタイトルや公開日など、どのようなデータを扱うかを定義しています。
例えば、z.string() は文字列、z.boolean() は真偽値を意味します。
z.coerce.date() は、日付をJavaScriptのDate型へ変換するための指定です。
公開日の日付形式について
今回、Markdownには次のように記述しています。
pubDate: 2026-11-01
日付だけを管理する場合は、このようなISO形式に統一しておくと扱いやすくなります。
ただし、日時やタイムゾーンまで扱う場合は注意が必要です。
例えば、日本時間の11月1日午前0時はUTCでは10月31日午後3時です。
そのため、toISOString() でUTCの日付を取り出すと、時刻によっては前日になる場合があります。
今回のような日付中心の運用であれば、変換ルールを統一し、必要以上に複雑な日時処理をしない方が管理しやすいと思います。
4. 記事ページを自動生成する
Markdownを読み込む設定ができたら、記事を表示するページを作ります。
今回は、記事URLを次のような形式にする例を考えます。
/blog/first-post/
src/pages/blog/[slug].astro を作成します。
---
import { getCollection, render } from 'astro:content';
import MigratedLayout from '../../layouts/MigratedLayout.astro';
export async function getStaticPaths() {
const posts = await getCollection(
'blog',
({ data }) => !data.draft
);
return posts.map((post) => ({
params: { slug: post.id },
props: { post },
}));
}
const { post } = Astro.props;
const { Content } = await render(post);
---
<MigratedLayout
title={post.data.title}
description={post.data.description ?? ''}
>
<article>
<h1>{post.data.title}</h1>
<Content />
</article>
</MigratedLayout>
少し難しいコードですが、役割を整理すると次のとおりです。
-
getCollection():記事を取得する -
getStaticPaths():生成する記事ページを決める -
render():Markdownを表示できる形にする -
<Content />:記事本文を表示する
WordPressでは、テーマが記事表示の仕組みを用意してくれていました。
Astroでは、その部分を自分で組み立てる必要があります。
AIに既存コードを修正してもらう場合
既存のプロジェクトがあるなら、必ずそのファイルをAIに渡した方がよいと思います。
現在のAstroプロジェクトに、Markdownの記事を表示する機能を追加したいです。
現在のディレクトリ構成と関連するAstroファイルを添付します。
既存のLayoutやCSSを維持したまま、記事を表示できるようにしてください。
ファイルを新規作成する場合と修正する場合を分けて説明してください。
既存のコードを必要以上に書き換えないでください。
このように指示しておけば、AIが新しい構成を一から作ってしまう問題を減らせます。
5. トップページに記事一覧を表示する
記事ページができたら、トップページにも記事一覧を表示します。
今回の移行作業では、getCollection('blog') を使って記事データを取得しました。
---
import MigratedLayout from '../layouts/MigratedLayout.astro';
import { getCollection } from 'astro:content';
const posts = (await getCollection('blog'))
.filter((p) => !p.data.draft);
const latest = posts
.map((p) => {
const date = p.data.pubDate
.toISOString()
.slice(0, 10);
const [year, month, day] = date.split('-');
return {
title: p.data.title,
date,
url: `/${year}/${month}/${day}/${p.id}/`,
categories: [
{ name: p.data.category }
],
};
})
.sort((a, b) => b.date.localeCompare(a.date));
---
これは、実際の移行作業で使用した記事取得処理を整理したものです。
このコードでは、公開日から年月日を取り出して記事URLを作成しています。
ただし、記事URLを日付付きにする必要がなければ、もっとシンプルにできます。
const url = `/blog/${p.id}/`;
今回のサイトは公開したばかりなので、既存URLの維持を絶対条件にはしていません。
今後も長く使うURL構造として、どちらが管理しやすいかを考えて決めることにしました。
記事一覧のHTMLやCSSについては、既存デザインに合わせて調整します。
6. SWELLのデザインを再現するつもりが、オリジナルデザインに変更
WordPressではテーマにSWELLを使用していました。最初は、既存のデザインをできるだけ維持したままAstroへ移行するつもりでした。そのため、現在のサイトのスクリーンショットや構成を参考にしながら、AIと一緒に再現する方法を検討していました。
しかし、作業を進める途中で方針を変更しました。せっかくWordPressからAstroへ移行するのなら、デザインも新しく作ってみようと。
Astroでは、HTMLやCSSを使って自由にレイアウトを構築できます。WordPressのテーマに合わせてデザインを再現するより、自分が作りたいサイトに合わせて構成を考え直すことにしました。
6-1. AIにオリジナルデザインを依頼する
既存のデザインを再現する場合と、オリジナルデザインを制作する場合では、AIへの指示方法も変わります。既存デザインの再現では、スクリーンショットを参考に、元のレイアウトへ近づけるよう依頼します。
一方、オリジナルデザインでは、サイトの目的や掲載する情報、希望する雰囲気を伝える必要があります。
例えば、次のような指示です。
現在WordPressからAstroへブログを移行しています。
既存のWordPressテーマのデザインを再現するのではなく、Astroでオリジナルデザインのサイトを作りたいです。
以下の条件でトップページを設計してください。
- Web制作やプログラミングの学習記録を掲載するブログ
- 記事を読みやすくする
- 新着記事が分かりやすい構成にする
- PC・タブレット・スマートフォンに対応する
- ヘッダーとフッターを共通化する
- Markdownの記事を自動的に一覧表示する
- HTMLとCSSを中心に構築する
- 不要なJavaScriptは使用しない
まずデザインとページ構成を提案してください。
その後、既存のAstroプロジェクトに組み込む方法を教えてください。
6-2. Layoutを使ってデザインを共通化
今回の作業では、MigratedLayout.astro というLayoutを使用しました。
トップページでは、次のように読み込んでいます。
---
import MigratedLayout from '../layouts/MigratedLayout.astro';
---
<MigratedLayout
title="ホーム"
description="わかったつもりを、わかるまで。Web制作とプログラミングを学び直す実験記録。"
>
<!-- トップページのコンテンツ -->
</MigratedLayout>
このLayoutに共通のHTML構造やデザインをまとめることで、ページごとの重複を減らせますWordPressでいう共通テンプレートに近い考え方です。また、記事一覧についてはContent Collectionsからデータを取得し、公開日順に表示する構成にしました。
6-3. デザインを変えても記事データはそのまま使える
今回の作業で便利だと感じたのは、記事データとデザインを分離できることです。
Markdownの記事データはそのままにして、LayoutやCSSを変更することで、サイトの見た目を調整できます。もちろんWordPressでもテーマやテンプレートを変更できますが、Astroでは自分で作成したコンポーネントを組み合わせて構築できます。
今回は、SWELLの見た目を維持することよりも、Astroで新しくサイトを構築する経験を優先しました。WordPressからAstroへの移行は、必ずしもデザインをそのまま引き継ぐ必要はない。今回の移行は、サイトの構成とデザインを見直す機会にもなりました。
7. Astroでビルドしてみる
トップページや記事ページができたら、公開用ファイルを生成します。ターミナルで、Astroのプロジェクトディレクトリに移動して次のコマンドを実行します。
npm run build
ビルドが成功すると、標準的な静的出力の構成では dist ディレクトリにHTMLやCSSなどが生成されます。例えば、次のような構成です。
dist/
├── index.html
├── blog/
│ └── first-post/
│ └── index.html
└── _astro/
└── ...
生成されるファイルの構成は、ルーティングやビルド設定によって異なります。
ビルド後の表示を確認する
次のコマンドで、ビルドしたサイトをローカルで確認できます。
npm run preview
開発サーバーで正常に表示されていても、ビルド時にエラーが発生することがあります。そのため、npm run dev だけで確認を終わらせず、必ずビルドも実行します。
8. サーバーへアップロードする前に
静的サイトとしてビルドできたら、公開用のファイルをサーバーに配置します。ただし、ビルドできたからといって、そのまま公開してよいわけではありません。
以下の項目を確認します。
記事がすべて表示されるか
WordPressから移行した記事数と、Astroで生成された記事数を比較します。記事が抜けていないか、本文が欠けていないかも確認します。
画像が正しく表示されるか
画像の参照先が正しいか確認します。WordPressの wp-content/uploads/ にある画像を移動した場合は、記事本文のURLも合わせて修正する必要があります。
内部リンクが正しいか
記事同士のリンクやカテゴリーへのリンクが、移行後も正常に機能するか確認します。
SEO関連の設定
タイトル、description、canonical URL、robots.txt、サイトマップなども確認します。既存のURLを変更した場合、必要に応じて301リダイレクトを設定します。
WordPressのファイルをすぐに削除しない
今回はWordPressを静的サイトへ置き換えますが、移行が完了するまでは、元のWordPressのデータを保管しておく必要があります。
XMLファイルだけでは完全なバックアップにはなりません。データベースとアップロードした画像、必要な設定情報も別途バックアップします。公開環境での動作確認が終わってから、不要なWordPressのファイルを整理するようにしましょう。
9. Gitでサイトを管理する
Astroでは、ローカルでファイルを編集するため、Gitを使って変更履歴を管理する方法が便利です。
例えば、変更内容を確認するには次のコマンドを実行します。
git status
ファイルを追加する場合は、
git add .
コミットする場合は、
git commit -m "Update Astro site"
とします。コメントは日本語でもOK。今回は、英語の勉強も兼ねて英語にしています。とても個人的な事情。
ところが、ここでもちょっとしたミスがありました。
git commit -a "edit : text"
このコマンドではエラーが発生します。コミットメッセージを指定するための -m が抜けていました。
正しくは、例えば次のように記述します。
git commit -am "edit: text"
ただし、-a では新しく作成したファイルは追加されません。新規ファイルを含む場合は、git add でステージングしてからコミットする必要があります。
こうした小さなミスも、Gitに慣れていないと意外と時間を取られます。
こちらもご参考にどうぞ。
AstroとGitでよく使うコマンドまとめ|初心者がつまずいたポイントも解説
10. 今後の記事投稿はどうする?
WordPressでは、管理画面から記事を書いて公開していました。Astroに移行すると、Markdownファイルを作成してビルドする流れになります。ただ、文章を書く作業までコードエディターで行う必要はありません。今後は、WordやGoogleドキュメントで執筆し、Markdownへ変換する方法も検討しています。
例えば、次のような流れです。
Googleドキュメントで記事を書く
↓
Markdownに変換する
↓
Frontmatterを追加する
↓
Astroのブログに配置する
↓
Gitで変更を管理する
↓
ビルドして公開する
ただし、これは現時点で検討している運用方法です。画像、リンク、表などが正しく変換できるかは、実際に試して確認する必要があります。
11. AIと一緒に作業して感じたこと
今回、Astroへの移行を進めて感じたのは、AIに相談できることで、初めて触る技術でも取り組みやすくなるということです。
例えば、エラーが発生したら、そのエラーメッセージをAIに渡して原因を調べる。
コードの意味が分からなければ、処理を分解して説明してもらう。
デザインを再現したければ、スクリーンショットと既存コードを渡して実装方法を考えてもらう。
こうした使い方ができます。ただし、AIが出したコードが必ず正しいとは限りません。実際のファイル構成に合っていなかったり、Astroのバージョンと異なる記述になっていたりする場合もあります。
そこで大切だと思ったのは、次の3点です。
- 一度に多くのことを依頼しすぎない
- 修正する前に、現在のコードをAIに渡す
- 変更したら、必ず自分で動作確認する
AIにすべてを任せるのではなく、AIに手伝ってもらいながら自分で理解していく。
今回の移行は、そんな作業になりました。
おわりに
WordPressからAstroへの移行は、思っていたほど単純ではありませんでした。
WordPressでは当たり前に使えていた記事管理、カテゴリー表示、共通パーツなども、Astroでは自分で構築する必要があります。
その一方で、サイトに必要な機能を整理しながら実装できることには魅力を感じています。
今回の移行を通じて改めて分かったのは、Webサイトを制作する際、必ずしも最初からすべての技術を理解している必要はないということです。
分からないところを調べ、AIに相談し、コードを修正し、動作を確認する。その積み重ねで、新しい技術にも取り組めます。
もちろん、WordPressが不要になったわけではありません。サイトの内容や更新体制によっては、WordPressの方が適している場合もあります。
今回の経験を、今後のWebサイト制作で技術を選択する際にも活かしていきたいと思います。