WordPressからの移行 Astro EmDash TypeScript パーマリンク リダイレクト

WordPressからEmDashへ移しても、記事のURLは/スラッグ/のまま変えずに済みます。EmDashのブログテンプレートは記事を/posts/スラッグ、固定ページを/pages/スラッグで表示しますが、Astroのページを1つ追加し、テンプレート内のリンクを直せば、WordPressのパーマリンク(/%postname%/)と同じURLで表示できます。

検証したのはEmDash 1.3.1のブログテンプレート(Node.js+SQLite)です。

リダイレクトではなくURLを揃える

WordPressのXML(WXR)を取り込むと、本文中の画像URLはEmDash側の画像に置き換わります。一方、記事同士の内部リンクは、ドメインを除いたWordPressのパス(/スラッグ/)になって残ります。

URLを/posts/スラッグに変えて301で転送する方法もありますが、その場合は本文の内部リンクがすべて一度リダイレクトを経由します。経由させないためには内部リンクを書き換える作業が別に必要になるので、URLを揃えるほうが手間は少なくなります。

記事と固定ページを同じ形のURLで表示する

src/pages/[slug].astroを作ります。スラッグに一致する記事を探し、なければ固定ページを探して、見つかったほうのテンプレートへAstro.rewrite()で処理を渡します。ブラウザに表示されるURLは変わりません。

---
import { getEmDashEntry, decodeSlug } from "emdash";

const slug = decodeSlug(Astro.params.slug);
if (!slug) {
	return Astro.rewrite("/404");
}

// WordPressと同じく末尾スラッシュ付きを正規のURLにする
if (!Astro.url.pathname.endsWith("/")) {
	return Astro.redirect(`${Astro.url.pathname}/${Astro.url.search}`, 301);
}

// 処理を渡した先のテンプレートで、このページを経由したと分かるようにする
Astro.locals.wpPermalink = true;

const { entry: post } = await getEmDashEntry("posts", slug);
if (post) {
	return Astro.rewrite(`/posts/${encodeURIComponent(slug)}`);
}

const { entry: page } = await getEmDashEntry("pages", slug);
if (page) {
	return Astro.rewrite(`/pages/${encodeURIComponent(slug)}`);
}

return Astro.rewrite("/404");
---

/postsや/searchのような固定のルートはAstroが優先するので、このページでは処理されません。記事と固定ページで同じスラッグがある場合は記事が表示されるので、移行前にスラッグの重複がないか確認しておきます。

/posts/スラッグを直接開いた時は301で転送する

このままだと/posts/スラッグも表示できてしまい、同じ記事が2つのURLで表示されます。記事のテンプレート(src/pages/posts/[slug].astro)の先頭で、[slug].astroを経由していないアクセスを/スラッグ/へ転送します。Astro.localsに入れた値は、Astro.rewrite()で処理を渡した先でも読めました。

if (!Astro.locals.wpPermalink) {
	return Astro.redirect(`/${encodeURIComponent(slug)}/`, 301);
}

固定ページのテンプレート(src/pages/pages/[slug].astro)にも同じ処理を入れます。

サイト内のリンクとcanonicalも新しいURLにする

テンプレートには、記事カード・検索結果・RSSで、/posts/から始まるリンクを作っている箇所があります。これを/スラッグ/の形に変えます。canonicalも、getSeoMeta()に渡すパスを`/${slug}/`にして揃えます。

管理画面のコレクションの設定にある「URL Pattern」も、/{slug}/に変更しておきます。EmDashは、メニューやサイトマップのURLをこのパターンから作ります。

元のサイトマップの全URLで確かめる

仕上げに、WordPressのサイトマップに載っているURLを全部、EmDash側で開いて確かめます。200か、301で転送した先が200なら問題ありません。

試したサイトでは、URLを揃える前、記事本文の内部リンク59件がすべて404になっていました。揃えた後は57件が表示でき、残りの2件は、WordPressでも404になる元からのリンク切れでした。サイトマップの記事・固定ページ・カテゴリにRSSと画像のURLを加えた140件も、すべて200、または301で転送した先が200でした。