CloudflareがWordPress後継のサーバーレスCMS「EmDash」をベータ公開
目次
WordPressが誕生して24年。インターネットの40%以上を動かす巨大CMSだが、プラグインのセキュリティ問題は年々深刻化している。Cloudflareが4月2日にベータ公開した EmDash は、この構造的な問題をアーキテクチャごと作り直すことで解決しようとしている。Astro 6.0をベースにしたフルスタックサーバーレスCMSで、MITライセンスのオープンソースだ。
「WordPress後継」と銘打ってはいるが、24年の蓄積があるWordPressとv0.1.0のEmDashでは正面から比べられない領域が多い。逆に、WordPressが構造的に解決できない問題をEmDashがゼロから設計し直している領域もある。両者の強みと弱みを、領域ごとに掘り下げてみた。
全体比較
| 観点 | WordPress | EmDash | どちらが有利か |
|---|---|---|---|
| 言語 | PHP | TypeScript | 用途次第 |
| テーマエンジン | 独自テンプレート(PHP) | Astro 6.0 | 用途次第 |
| データストア | MySQL/MariaDB | D1(SQLite互換) | WordPress(実績) |
| ホスティング | どこでも。月数百円の共用サーバーでも動く | Cloudflare Workers、またはworkerdが動く環境 | WordPress(選択肢の広さ) |
| プラグイン数 | 59,000+ | エコシステムはこれから | WordPress(圧倒的) |
| テーマ数 | 12,000+(公式ディレクトリ) | 公式テーマ数本 | WordPress(圧倒的) |
| プラグインの隔離 | なし。フルアクセス | V8 isolateで完全分離 | EmDash(構造的優位) |
| 管理画面 | 成熟。非エンジニアでも扱える | 基本機能はあるが発展途上 | WordPress(完成度) |
| コミュニティ | 巨大。日本語情報も豊富 | ほぼゼロからのスタート | WordPress(圧倒的) |
| ライセンス | GPLv2 | MIT | EmDash(自由度) |
| 初期コスト | 無料〜月数百円 | Cloudflare無料枠で動作可能 | 互角 |
| スケーラビリティ | サーバー増強やCDNが別途必要 | エッジで動作、オートスケール | EmDash |
| 認証 | パスワード(2FAはプラグイン) | パスキー標準 | EmDash |
| コンテンツ課金 | WooCommerce等プラグインで対応 | x402ビルトイン | EmDash(手軽さ) |
| AIエージェント連携 | REST API(後付け) | MCPサーバー内蔵 | EmDash |
| 多言語対応 | プラグインで対応(WPML、Polylang等。成熟) | Astro i18n + エッジルーティング(組み込み) | 用途次第 |
EmDashが勝っている項目はアーキテクチャに由来するもので、WordPressが後から追いつくのは構造的に難しい。WordPressが勝っている項目はエコシステムの厚さに由来するもので、EmDashが追いつくには数年単位の時間がかかる。どちらの差も簡単には埋まらない。
EmDashが構造的に勝つ領域
WordPressのプラグインセキュリティ問題
WordPressのプラグインは、インストールした瞬間にサイトのデータベースとファイルシステムへのフルアクセスを手にする。サンドボックスも権限分離もない。PHPの add_action や add_filter でWordPressのあらゆるフックに割り込めるし、$wpdb 経由で生SQLも実行できる。つまりプラグインを1つ入れるとは、見知らぬ開発者にサーバーのrootを渡すのに近い行為だった。
graph LR
subgraph WordPressのプラグインモデル
P[プラグイン] -->|add_action/add_filter| H[全フック]
P -->|$wpdb| DB[(MySQL)]
P -->|file_get_contents等| FS[ファイルシステム]
P -->|wp_remote_get等| NET[外部ネットワーク]
end
この設計が生んだ被害は数字に表れている。
| 指標 | 数値 |
|---|---|
| 2025年のWordPressエコシステム新規脆弱性 | 10,794件(1日平均30件) |
| 脆弱性の発生源がプラグイン | 96% |
| 認証なしで悪用可能な脆弱性 | 43%以上 |
| 高深刻度の脆弱性(2025年) | 過去2年の合計を超過 |
| 脆弱性を知りながら修正しなかった開発者 | 52% |
Patchstackのレポートによると、2026年のCVE総数は前年比15%増の約55,000件に達する見込みで、WordPress.orgのプラグイン審査キューは800件以上が滞留し、処理に最低2週間かかっている。
ただし、この数字だけでWordPressが危険だと断じるのはフェアではない。59,000以上のプラグインがあれば脆弱性の総数が多くなるのは当然だ。問題は「1つの脆弱なプラグインがサイト全体を危険にさらす」というアーキテクチャにある。そしてこの問題はWordPressが後付けで解決するのが極めて難しい。PHPの同一プロセスでプラグインを実行するモデルは、WordPressの根幹に組み込まれているからだ。
EmDashは各プラグインをDynamic Workerと呼ばれる独立したV8 isolateの中で実行する。
V8 isolateとは
V8はGoogle ChromeやNode.jsが使うJavaScriptエンジンで、isolate(アイソレート)はその中の独立した実行環境を指す。各isolateは自分のヒープメモリを持ち、他のisolateのメモリには一切アクセスできない。Dockerコンテナのような仮想化とは異なり、OSレベルの仮想化オーバーヘッドがないため起動がミリ秒単位で完了する。Cloudflareの公称ではコンテナ比100倍高速だ。
隔離モデルの比較
| 観点 | WordPress | EmDash |
|---|---|---|
| プラグインの実行環境 | PHPの同一プロセス内 | プラグインごとに独立したV8 isolate |
| メモリ空間 | 共有(他のプラグインのメモリを読める) | 完全分離 |
| DB操作 | $wpdb で生SQL実行可能 | API経由のみ。生SQLは書けない |
| ファイルシステム | フルアクセス | アクセス不可 |
| ネットワーク | 制限なし | 明示的にホスト名を許可しない限り不可 |
| 権限モデル | 全権委任(インストール=フルアクセス) | ケーパビリティベース(宣言した権限のみ付与) |
| 脆弱なプラグインの影響範囲 | サイト全体(DB、ファイル、他プラグイン) | そのプラグインに付与された権限の範囲内 |
WordPressでは、1つのプラグインが侵害されるとサイト全体のデータベース、ファイルシステム、他のプラグイン、さらには同一サーバー上の他サイトまで危険にさらす。EmDashでは、最悪の場合でもそのプラグインに付与された権限の範囲内で被害が止まる。
Cloudflare Workersのセキュリティモデルは多層防御になっている。
| レイヤー | 保護内容 |
|---|---|
| V8 isolate | メモリ空間の完全分離 |
| プロセスサンドボックス | Linuxネームスペース + seccompでファイルシステム・ネットワークを遮断 |
| コードン分離 | 信頼レベル別にWorkerをプロセスグループに分離(Freeプランとエンタープライズは同居しない) |
| ハードウェア保護 | ランダムなメモリ保護キーでヒープデータを保護(バグがあっても92%の確率でハードウェアトラップ) |
| タイミング攻撃対策 | コード実行中は Date.now() を固定値に。マルチスレッドも提供しないためサイドチャネル攻撃を構造的に排除 |
WordPressにこれと同等の防御を後付けするのは、言語レベルの制約から事実上不可能だ。PHPのプロセスモデルでは、プラグイン間のメモリ分離もファイルシステムの隔離も実現できない。WAFやMalware Scannerで外側から守ることはできるが、プラグインが内側から暴れることを防ぐ手段はない。
ケーパビリティベースのアクセス制御
EmDashのプラグインは、マニフェストで宣言したケーパビリティ(権限)だけがbinding経由で注入される。データベースやファイルシステムへの直接アクセスは存在しない。
import { definePlugin } from "emdash";
export default () => definePlugin({
id: "notify-on-publish",
version: "1.0.0",
capabilities: ["read:content", "email:send"],
hooks: {
"content:afterSave": async (event, ctx) => {
// ctx にはread:contentとemail:sendの
// ケーパビリティだけがbindingされている
// DBへの直接アクセスやネットワーク接続は不可能
}
}
});
WordPressのプラグインがインストール時に「何ができるか」をユーザーに明示する仕組みは存在しない。Androidアプリがインストール時にパーミッションを要求するのと対照的に、WordPressプラグインは黙って全権を手にする。EmDashのケーパビリティモデルはAndroidのパーミッションに近く、ユーザーが何を許可しているのかが明確になる。
ただし、ケーパビリティベースのモデルにも限界はある。read:content の権限を持つプラグインは、そのスコープ内のコンテンツすべてを読める。「この記事だけ」「このフィールドだけ」といった粒度の制御がどこまで可能かは、ベータ段階の現時点ではドキュメントが不十分で判断しづらい。
graph LR
subgraph WordPress
WP_Plugin[プラグイン] -->|フルアクセス| WP_DB[(データベース)]
WP_Plugin -->|フルアクセス| WP_FS[ファイルシステム]
WP_Plugin -->|制限なし| WP_Net[外部ネットワーク]
end
subgraph EmDash
ED_Plugin[プラグイン<br/>Dynamic Worker] -->|read:content のみ| ED_DB[(D1)]
ED_Plugin -->|email:send のみ| ED_Email[メール送信API]
ED_Plugin -.-x|アクセス不可| ED_FS[ファイルシステム]
ED_Plugin -.-x|アクセス不可| ED_Net[外部ネットワーク]
end
パフォーマンスとスケーラビリティ
WordPressはPHP + MySQLのクラシックなサーバーサイドアーキテクチャだ。リクエストのたびにPHPがHTML全体を生成し、MySQLにクエリを投げる。高速化にはページキャッシュプラグイン、CDN、場合によってはVarnishやRedisといったインフラ層の追加が必要になる。
EmDashはCloudflare Workersで動作し、リクエストはユーザーに最も近いエッジロケーションで処理される。キャッシュ層もCDNも別途構築する必要がない。データストアのD1もエッジに配置されるため、DBクエリのレイテンシも小さい。
graph TD
A[ブラウザ] -->|リクエスト| B[Cloudflare Workers<br/>EmDashコア]
B --> C[Astro 6.0<br/>テーマエンジン]
B --> D[D1<br/>SQLite互換DB]
B --> E[R2<br/>メディアストレージ]
B -->|capability binding| F[Dynamic Worker<br/>プラグインA]
B -->|capability binding| G[Dynamic Worker<br/>プラグインB]
F -.->|許可された操作のみ| D
G -.->|許可された操作のみ| E
| 観点 | WordPress | EmDash |
|---|---|---|
| 実行環境 | オリジンサーバー | エッジ(世界300+ロケーション) |
| スケールアップ | サーバー増強、ロードバランサー追加 | 自動(Workers基盤が処理) |
| スケールダウン | サーバーは動き続ける(固定コスト) | リクエストゼロならコストゼロ |
| キャッシュ | プラグイン+CDNで構築 | エッジキャッシュが標準 |
| DB接続 | オリジンからMySQLへのTCP接続 | エッジからD1へのローカルアクセス |
| Cold start | PHPプロセス起動(数百ms) | V8 isolate起動(数ms) |
WordPressはトラフィックが急増するとサーバーが落ちる。ニュースサイトがバズった時に503を返すのは日常茶飯事で、対策にはインフラエンジニアの手が必要だ。EmDashはCloudflareの基盤に乗っている限り、スパイクに対して構造的に耐性がある。
ただし、WordPressのパフォーマンス問題はプラグインで十分に実用レベルまで解決できるケースが多い。WP RocketやCloudflare APOを使えば、静的サイト並みの速度は出る。「パフォーマンスのためにCMSを乗り換える」ほどの差が出るかは、サイトの規模と要件次第だ。
デフォルト認証の堅さの違い
| 観点 | WordPress | EmDash |
|---|---|---|
| デフォルト認証 | パスワード | パスキー(パスワードレス) |
| 2FA | プラグインで追加 | 不要(パスキーが多要素認証を兼ねる) |
| SSO連携 | プラグインで対応(SAML/OIDC/LDAP) | プラグインで対応(IdPメタデータ自動プロビジョニング) |
| パスワードDB | 存在する(bcryptハッシュ) | 存在しない |
EmDashはパスワードの保存そのものがない。パスワードが存在しなければ、パスワードリスト攻撃もブルートフォースも成立しない。WordPress側はデフォルトがパスワード認証で、2FAの導入はサイト管理者の判断に委ねられている。ロールはどちらもadministrator、editor、author、contributorの4段階。
ただしWordPressの認証プラグインは十分に成熟していて、miniOrangeやWP SAML Authなどのプラグインでエンタープライズ級のSSO環境を構築できる。Active DirectoryやLDAPとの統合も実績が豊富だ。EmDashのSSO連携はこれから検証が進む段階で、エンタープライズ要件を満たせるかは未知数。
パスワードDBなしで認証できる仕組み
「パスワードDBが存在しない」と書いたが、サーバー側に何も保存しないわけではない。パスキー(FIDO2/WebAuthn)は公開鍵暗号を使った認証方式で、サーバーが保存するのはパスワードハッシュではなく公開鍵だ。
登録時の流れはこうなる。
- サーバーがチャレンジ(ランダムな値)を生成してブラウザに送る
- ブラウザが認証器(デバイスのセキュリティチップやUSBキー)に鍵ペアの生成を要求
- ユーザーが生体認証(指紋・顔)またはPINで本人確認
- 認証器が秘密鍵と公開鍵のペアを生成し、秘密鍵はデバイス内に保持
- 公開鍵とクレデンシャルIDをサーバーに送信し、サーバーはこれだけを保存
ログイン時は、サーバーがチャレンジを送り、デバイスの秘密鍵で署名し、サーバーが公開鍵で署名を検証する。パスワードのやり取りは一切発生しない。
sequenceDiagram
participant U as ユーザー
participant B as ブラウザ
participant A as 認証器<br/>(セキュリティチップ)
participant S as EmDashサーバー
Note over U,S: 登録フロー
B->>S: 登録リクエスト
S->>B: チャレンジ + サーバー情報
B->>A: 鍵ペア生成要求
U->>A: 生体認証 or PIN
A->>A: 秘密鍵・公開鍵ペア生成
A->>B: 公開鍵 + クレデンシャルID + 署名
B->>S: 公開鍵 + クレデンシャルID + 署名
S->>S: 公開鍵を保存(パスワードは保存しない)
Note over U,S: 認証フロー
B->>S: ログインリクエスト
S->>B: チャレンジ + クレデンシャルID
B->>A: 署名要求
U->>A: 生体認証 or PIN
A->>A: 秘密鍵でチャレンジに署名
A->>B: 署名データ
B->>S: 署名データ
S->>S: 保存済み公開鍵で署名を検証
ポイントは、公開鍵が漏洩してもセキュリティ上の問題にならないこと。公開鍵から秘密鍵を逆算することは計算量的に不可能なので、パスワードハッシュの漏洩とはリスクの性質が根本的に異なる。
| 漏洩した場合 | パスワードDB | パスキーの公開鍵DB |
|---|---|---|
| オフライン総当たり攻撃 | 可能(弱いパスワードは数秒で解読) | 不可能(公開鍵から秘密鍵は導出できない) |
| クレデンシャルスタッフィング | 可能(使い回しパスワードで他サイトに侵入) | 不可能(鍵ペアはサイトごとに一意) |
| フィッシング | 有効(偽サイトでパスワードを入力させる) | 無効(認証器がオリジンを検証し、偽サイトでは署名しない) |
| DB漏洩後の対応 | 全ユーザーにパスワード変更を強制 | 対応不要(公開鍵だけでは認証できない) |
パスキーが「多要素認証を兼ねる」のもこの仕組みによる。認証に必要なのはデバイスの所持(所有要素)と生体認証またはPIN(知識/生体要素)の2つ。1回の操作で2要素認証が完了するため、WordPressで2FAプラグインを別途導入する手間がそもそも要らない。
コンテンツ課金
EmDashはx402という「インターネットネイティブな決済の標準規格」をビルトインでサポートしている。コンテンツに価格とウォレットアドレスを設定するだけで、記事単位の従量課金が実装できる。エンジニアリング作業はゼロだとCloudflareは主張している。
WordPressで同等のことをやるにはWooCommerce + MemberPressの組み合わせが必要になる。決済プロバイダの契約、Stripeの設定、Webhookの構築、会員管理プラグインの導入と設定。動くようになるまでに数日から数週間かかる。しかもプラグイン間の互換性問題が頻繁に発生する。
一方で、WordPressのEC/課金プラグイン群は多様なビジネスモデルに対応できる。月額サブスクリプション、従量課金、クーポン、アフィリエイト、物理商品との統合。x402は記事単位の課金には向いているが、複雑な販売フローには対応しきれない可能性がある。
AIエージェント連携
各EmDashインスタンスにはModel Context Protocol(MCP)サーバーが内蔵されている。EmDash CLIからメディアアップロード、コンテンツ検索、スキーマ管理などをプログラマティックに操作でき、AIエージェントとの統合を前提にした設計だ。
プラグイン作成やテーマ移行のためのAgent Skillも用意されており、「Block Kit Agent Skill」でWordPressのブロックをEmDash向けに変換できる。
WordPressにもREST APIはあるが、後付けで追加されたもので、認証の設定やプラグインとの競合に悩まされることがある。MCPサーバーがビルトインという設計は、2026年のCMS選定基準として「AIエージェントとの親和性」を重視するなら、EmDashの明確なアドバンテージだ。
テーマ開発: PHP vs Astro
EmDashのテーマはAstroプロジェクトそのものだ。Pages、Layouts、Components、Styles、そしてSeedファイル(コンテンツタイプとフィールドを定義するJSON)で構成される。テーマにもデータベース操作の権限がない。コンテンツの取得はEmDashが提供するAPIを通じて行い、生SQLを書く余地がない。テーマとプラグインの両方でデータベースへの直接アクセスを排除することで、SQLインジェクションの攻撃面を構造的にゼロにしている。
WordPressのテーマはPHPファイルなので、テーマ内で $wpdb->query() を呼ぶことも、file_get_contents() で外部にリクエストを飛ばすこともできてしまう。実際、WordPress.orgのテーマディレクトリでもマルウェアを含むテーマが定期的に発見されている。EmDashではこの攻撃経路自体が存在しない。
| 観点 | WordPress テーマ | EmDash テーマ |
|---|---|---|
| 言語 | PHP(テンプレートタグ) | Astro + TypeScript |
| カスタマイズ | テーマカスタマイザー(GUI) | コード編集(CLI/エディタ) |
| テーマストア | 12,000+(無料/有料) | 公式数本(これから) |
| DB操作 | 可能(生SQL含む) | 不可能(API経由のみ) |
| セキュリティリスク | テーマ経由のマルウェアが存在 | 攻撃面がない |
| 学習コスト | PHPの基礎でOK | フロントエンド開発の知識が必要 |
| ノーコード対応 | テーマカスタマイザー、Gutenberg | なし |
開発者にとってはAstro + TypeScriptのほうがモダンで書きやすいが、非エンジニアにとってはWordPressのテーマカスタマイザーやGutenbergのほうが圧倒的にアクセスしやすい。この差は技術の問題ではなく、ターゲットユーザーの違いだ。
WordPressが明確に勝つ領域
エコシステムの厚み
59,000以上のプラグインと12,000以上のテーマ。何かやりたいことがあれば、だいたい既存プラグインで解決する。ECサイトならWooCommerce、SEOならYoast SEO、フォームならContact Form 7、バックアップならUpdraftPlus。それぞれのプラグインに専門の開発者コミュニティがあり、ドキュメントもチュートリアルも豊富だ。
EmDashのプラグインエコシステムは文字通りゼロからのスタートだ。SEOプラグイン、フォームビルダー、バックアップツール、メール配信連携。WordPressで当たり前に使えるものの多くが、EmDashではまだ存在しないか、自分で作る必要がある。
非エンジニアの運用性
WordPressは20年以上かけて「ITに詳しくない人でも使えるCMS」としての地位を確立してきた。管理画面はブラウザだけで完結し、記事の投稿、画像のアップロード、テーマの変更、プラグインのインストールまでGUIで行える。Gutenbergエディタのブロックベースの編集は、Notionライクな体験に近づいている。
EmDashの管理画面は機能的に必要最低限で、ターゲットが明らかにエンジニア寄りだ。テーマのカスタマイズにはコードを書く必要があるし、プラグイン開発もTypeScriptの知識が前提になる。「ブログを書きたいだけの人」にとって、EmDashは過剰に技術的だ。
ホスティングの自由度
WordPressは月額数百円のレンタルサーバーから、AWS上のエンタープライズ構成まで、あらゆる環境で動く。さくらインターネット、エックスサーバー、ロリポップ。日本のレンタルサーバーのほとんどがWordPressのワンクリックインストールに対応している。自社サーバーに置くこともクラウドに置くこともできるし、サーバーの引っ越しも確立された手順がある。
EmDashの最適な実行環境はCloudflare Workersだ。workerd(Cloudflare Workersのオープンソースランタイム)を使えば他の環境でも動作するとされているが、現時点でworkerdでのセルフホスティングの実績はほぼない。実質的にCloudflareに依存する運用になりやすく、Cloudflareのサービス変更や価格改定の影響を直接受ける。ベンダーロックインとまでは言えないが、WordPress比で選択肢は大幅に狭い。
情報量とコミュニティ
WordPressで困ったことがあれば、検索すればほぼ確実に日本語の解決策が見つかる。Stack Overflow、Qiita、Zenn、個人ブログ。日本語の書籍も数十冊は出ている。WordPressの開発者を雇うのも簡単で、PHPとWordPressの経験者は世界中にいる。
EmDashで困ったら、現時点では公式ドキュメントとGitHubのIssueしか頼るものがない。日本語の情報はゼロに等しい。開発者の採用も難しく、「EmDash経験者」という人材はまだ存在しない。
既存資産と業務フロー
WordPressで構築された数億のサイトが存在し、それぞれにカスタマイズされたテーマ、プラグイン設定、運用フローが確立されている。移行ツールがあっても、業務フローの再構築コストは技術的な移行コストより大きい。
WooCommerceで構築したECサイト、bbPressで動いているフォーラム、LearnDashで作ったオンラインコース。プラグインに依存した複雑なサイトほど移行のハードルは高い。EmDashのプラグインエコシステムがこれらをカバーするには年単位の時間がかかる。
WordPressからの移行
WordPress管理画面からWXRファイル(WordPress eXtended RSS)をエクスポートしてインポートする方法と、EmDash Exporterプラグインをインストールしてセキュアなエンドポイント経由で移行する方法の2つが用意されている。後者はWordPressのアプリケーションパスワードで保護され、メディアファイルの自動移行にも対応する。移行にかかる時間は「数分」とのこと。
カスタム投稿タイプはEmDashのCollectionsに変換される。WordPressテーマの移行には wordpress-theme-to-emdash というAgent Skillが用意されている。
コンテンツの移行は比較的容易だが、テーマのルック&フィールの再現とプラグイン機能の置き換えが本当のボトルネックになる。シンプルなブログなら「数分」で移行できるだろうが、プラグインを10個以上使っているサイトでは、移行プロジェクト自体が数週間かかる可能性がある。
v0.1.0ベータの中身
現在のバージョンはv0.1.0プレビューベータ。npm create emdash@latest で即座にセットアップでき、Cloudflareへのワンクリックデプロイボタンも提供されている。管理画面を試すだけならemdashcms.comのPlaygroundがある。GitHubリポジトリはemdash-cms/emdashで、MITライセンス。
Cloudflareはここ数ヶ月、Workers上で動くプラットフォームを矢継ぎ早に出している。VoidZeroのViteネイティブデプロイプラットフォーム、vinextによるNext.jsの再実装、そしてWorkers上のリアルタイム分析基盤。EmDashはこの流れの延長にある。
Webサイトにサードパーティスクリプトが仕込む脅威については、Cloudflareが先日公開したClient-Side SecurityのGNN+LLM検出でも取り上げた。EmDashはそもそもプラグインが悪事を働けないアーキテクチャにすることで、問題の根を断とうとしている。
多言語対応
最近のWebサイトは多言語対応を求められる場面が増えている。越境ECやグローバル企業のコーポレートサイトはもちろん、個人ブログでも英語版を用意するケースが珍しくなくなった。WordPressとEmDashでは、多言語化のアプローチが根本的に異なる。
WordPressの多言語対応
WordPress本体には多言語機能がない。多言語化にはWPML、Polylang、TranslatePressといったプラグインを導入する必要がある。
| プラグイン | 方式 | 価格 | 特徴 |
|---|---|---|---|
| WPML | 投稿を言語ごとに複製 | 有料($39〜/年) | 最も普及。WooCommerceとの統合が強い |
| Polylang | 投稿を言語ごとに複製 | 無料版あり | WPMLより軽量。無料で始められる |
| TranslatePress | フロントエンドから翻訳を編集 | 無料版あり | 見た目を確認しながら翻訳できる |
| MultilingualPress | マルチサイトで言語ごとにサイトを分離 | 有料 | エンタープライズ向け。サイト間の独立性が高い |
WPMLとPolylangは「投稿を言語ごとに複製する」方式で、日本語の記事と英語の記事が別々の投稿として管理される。記事数が2倍、3倍に膨れ上がり、管理が煩雑になる。言語スイッチャーの配置、hreflangタグの出力、URL構造の設定(サブディレクトリ /en/ かサブドメイン en.example.com か)まで、プラグインの設定項目は多い。
さらに、多言語プラグインは他のプラグインとの互換性問題が発生しやすい。キャッシュプラグインが言語別のページをキャッシュし損ねたり、SEOプラグインが正しいhreflangを出力しなかったり、ECプラグインの商品ページの翻訳でフィールドが欠落したり。プラグイン同士の組み合わせが爆発的に増えるため、トラブルシューティングに時間を取られがちだ。
ただし、これらのプラグインは10年以上の実績があり、翻訳メモリ、翻訳者ロール管理、翻訳進捗トラッキング、外部翻訳サービス(DeepL、Google翻訳)との統合など、業務で必要な機能は一通り揃っている。大規模な多言語サイトの運用ノウハウも蓄積されている。
EmDashの多言語対応
EmDashはAstro 6.0のビルトインi18nルーティングをベースにしている。Astroのi18n機能はフレームワークレベルで言語別ルーティングをサポートしており、プラグインの後付けではなく設計に組み込まれている。
// astro.config.ts(EmDashテーマ側の設定)
export default defineConfig({
i18n: {
defaultLocale: "ja",
locales: ["ja", "en", "zh-hans", "ko"],
routing: {
prefixDefaultLocale: false
// ja: /articles/slug
// en: /en/articles/slug
}
}
});
Cloudflare Workersで動作する利点が大きいのは、ロケール検出とコンテンツ振り分けの部分だ。
graph TD
A[ブラウザ] -->|リクエスト| B[Cloudflare Workers<br/>エッジロケーション]
B -->|Accept-Language<br/>CF-IPCountry| C{ロケール判定}
C -->|ja| D[日本語コンテンツ]
C -->|en| E[英語コンテンツ]
C -->|zh-hans| F[中国語コンテンツ]
D --> G[D1から取得<br/>エッジキャッシュ]
E --> G
F --> G
WordPressの多言語プラグインはオリジンサーバーでロケール判定を行い、該当する言語の投稿をMySQLから取得する。EmDashではCloudflare Workersがエッジでロケールを判定し、D1から言語別コンテンツを返す。リクエストがオリジンに到達する前にすべてが完結するため、多言語サイト特有の「言語判定 → リダイレクト → コンテンツ取得」のレイテンシが構造的に小さい。
D1のコンテンツスキーマでは、翻訳がCollectionsのフィールドとして管理される。投稿を言語数だけ複製するWordPressの方式と異なり、1つのコンテンツエントリに複数言語のフィールドが紐づく。
| 観点 | WordPress | EmDash |
|---|---|---|
| 多言語の実装 | プラグイン(後付け) | フレームワーク組み込み |
| コンテンツ構造 | 言語ごとに投稿を複製 | 1エントリに複数言語フィールド |
| URL構造 | プラグインの設定に依存 | Astro i18nルーティング |
| ロケール検出 | オリジンサーバーで処理 | エッジで処理 |
| hreflangタグ | プラグインが出力 | フレームワークが自動出力 |
| 翻訳管理 | 翻訳メモリ、進捗管理、翻訳者ロール | 基本的なフィールド管理のみ |
| 機械翻訳連携 | DeepL、Google翻訳プラグインあり | API経由で可能だが公式統合はまだ |
| RTL対応 | プラグインで対応可能 | Astroのdir属性で対応 |
| 実績 | 数百万の多言語サイトが稼働中 | ベータ段階 |
EmDashのアーキテクチャ的な優位性は明確だが、翻訳ワークフローの成熟度ではWordPressに大きく差をつけられている。翻訳メモリ(過去の翻訳を再利用して一貫性を保つ仕組み)、翻訳者ごとのロール管理、翻訳の進捗トラッキング、翻訳エージェンシーとの連携。企業の多言語サイト運用で必要になるこれらの機能は、EmDashでは未整備だ。
個人ブログや小規模サイトなら、EmDashのフレームワーク組み込み方式のほうがシンプルで扱いやすい。プラグインの互換性を気にする必要がなく、エッジでの高速な言語振り分けが最初から使える。一方、50言語対応の企業サイトや、翻訳者チームが並行作業する大規模プロジェクトでは、WordPressの翻訳プラグイン群が提供するワークフロー支援が不可欠になる。
URL構造とルーティング
業務でCMSを使う場合、ドメイン構成やパーマリンク(URL構造)のカスタマイズは避けて通れない。SEOの都合でURLにカテゴリを含めたい、リダイレクトルールを細かく制御したい、サブディレクトリ配下に設置したい。WordPressではこのあたりを functions.php で柔軟にいじれるのが強みだった。
WordPressのURL制御
WordPressのパーマリンク設定は管理画面のGUIでも変更できるが、業務レベルのカスタマイズは functions.php でRewrite APIを叩くことになる。
// functions.php: カスタム投稿タイプのURLを /news/slug/ にする
function custom_news_rewrite() {
add_rewrite_rule(
'^news/([^/]+)/?$',
'index.php?post_type=news&name=$matches[1]',
'top'
);
}
add_action('init', 'custom_news_rewrite');
// パーマリンク構造を /%category%/%postname%/ に変更
function custom_permalink_structure() {
global $wp_rewrite;
$wp_rewrite->set_permalink_structure('/%category%/%postname%/');
}
.htaccess(Apache)や nginx.conf でのリダイレクトルール追加、add_rewrite_tag によるカスタムクエリ変数の登録、template_redirect フックでの条件分岐リダイレクトなど、PHPレベルで何でもできる。20年分のStack Overflowの回答が蓄積されているので、やりたいことを検索すればほぼ確実にコード片が見つかる。
EmDashのURL制御
EmDashはAstro 6.0ベースなので、ルーティングもAstroの仕組みに従う。Astroのルーティングはファイルベースで、src/pages/ ディレクトリのファイル構造がそのままURLになる。TypeScriptで書ける。
src/pages/
├── index.astro → /
├── about.astro → /about
├── articles/
│ └── [slug].astro → /articles/any-slug
└── [lang]/
└── articles/
└── [slug].astro → /en/articles/any-slug
動的ルーティングは [slug].astro や [...path].astro(キャッチオール)で実現する。getStaticPaths() で生成するパスを制御できるため、カテゴリ付きURLも表現可能だ。
// src/pages/[category]/[slug].astro
export async function getStaticPaths() {
const posts = await getCollection("posts");
return posts.map((post) => ({
params: {
category: post.data.category,
slug: post.slug,
},
props: { post },
}));
}
// → /tech/my-article, /diary/my-diary のようなURLが生成される
リダイレクトは astro.config.ts で宣言的に書ける。
// astro.config.ts
export default defineConfig({
redirects: {
"/old-path": "/new-path",
"/blog/[...slug]": "/articles/[...slug]",
},
});
WordPressの functions.php + Rewrite APIに相当する柔軟性は、Astroのファイルベースルーティング + astro.config.ts + ミドルウェアの組み合わせでカバーできる。ミドルウェアを使えばリクエストの前処理(認証チェック、リダイレクト、ヘッダー操作)もTypeScriptで書ける。
// src/middleware.ts
import { defineMiddleware } from "astro:middleware";
export const onRequest = defineMiddleware(async (context, next) => {
const url = new URL(context.request.url);
// /old-blog/* を /articles/* にリダイレクト
if (url.pathname.startsWith("/old-blog/")) {
const newPath = url.pathname.replace("/old-blog/", "/articles/");
return context.redirect(newPath, 301);
}
return next();
});
URL制御の比較
| 観点 | WordPress | EmDash (Astro) |
|---|---|---|
| パーマリンク設定 | GUI + functions.php | astro.config.ts + ファイル構造 |
| 動的ルーティング | Rewrite API(正規表現) | [slug].astro(ファイルベース) |
| リダイレクト | .htaccess / functions.php | astro.config.ts / ミドルウェア |
| ミドルウェア | フックシステム(actions/filters) | src/middleware.ts(TypeScript) |
| サブディレクトリ配置 | site_url / home_url 設定 | base オプション |
| カスタムクエリ変数 | add_rewrite_tag | URLパラメータ / Astro.url.searchParams |
| 言語 | PHP | TypeScript |
| 情報量 | 膨大(20年分の事例) | Astro公式ドキュメント中心 |
「TypeScriptでルーティングを書けるのか?」という疑問に対する答えはイエスだ。むしろAstroのファイルベースルーティングはWordPressのRewrite APIより直感的で、正規表現地獄に陥りにくい。ミドルウェアの仕組みも functions.php のフックシステムより見通しが良い。
ただし、EmDashのルーティングがCloudflare Workers上でどこまで自由に動くかは別の話だ。Astro単体なら何でもできるが、EmDashはプラグインとテーマのサンドボックス化を優先している。テーマ側のルーティングに制約がかかっている可能性はある。ベータ段階ではこのあたりのドキュメントが薄く、実際に試してみないとわからない部分が多い。
WordPress側のRewrite APIは強力だが、内部的にはすべてのルールが wp_options テーブルに rewrite_rules として保存され、リクエストのたびにマッチングが走る。ルールが増えるほどパフォーマンスに影響する設計で、大規模サイトでは flush_rewrite_rules() のタイミングに気を遣う必要がある。EmDash(Astro)のファイルベースルーティングはビルド時に解決されるため、ランタイムのオーバーヘッドがない。
WordPressの24年
記事の冒頭で「24年」と書いたが、この数字の重みを簡単に振り返っておく。
2003年、当時19歳のMatt MullenwegがMike Littleと共にb2/cafelogというPHP製ブログツールをフォークして作ったのがWordPressの始まりだ。当初は個人ブログ用の小さなツールに過ぎなかった。
| 年 | ver | 出来事 |
|---|---|---|
| 2003 | 0.70 | b2/cafelogからフォークして誕生 |
| 2004 | 1.2 | プラグインAPIを導入。エコシステムの起点 |
| 2005 | 1.5 | テーマシステム導入。同年Automattic社設立 |
| 2005 | 2.0 | WYSIWYGエディタ搭載 |
| 2008 | 2.5 | 管理画面の大幅リデザイン |
| 2010 | 3.0 | カスタム投稿タイプ追加。「ブログ」から「CMS」への転換点 |
| 2011 | — | WooCommerce登場。ECプラットフォームとしても確立 |
| 2015 | 4.4 | REST APIをコアに統合 |
| 2018 | 5.0 | Gutenbergブロックエディタ導入。コミュニティを二分する論争に |
| 2024 | 6.x | Mullenweg vs WP Engine紛争。ガバナンス問題が表面化 |
| 2026 | 6.8+ | Webの40%超を占有。年間脆弱性報告は1万件超 |
転換点は2010年のWordPress 3.0だ。カスタム投稿タイプの導入で、ブログ以外の用途(ECサイト、企業サイト、ポートフォリオ、不動産サイト)にWordPressが使われ始めた。翌2011年にWooCommerceが登場し、WordPressはEC基盤としても定着した。
2018年のGutenberg導入は最も物議を醸した変更だった。クラシックエディタからブロックベースの編集に強制移行する方針に「既存のワークフローが壊れる」と猛反発が起き、旧エディタを復元するClassic Editorプラグインのインストール数は500万を超えた。今でも現役だ。
2024年にはWordPressの創始者MullenwegがWP Engineを公の場で批判し、WordPress.orgのプラグインディレクトリからWP Engine関連プラグインへのアクセスを一時遮断した。オープンソースのガバナンスと商業利用の境界について、コミュニティ全体の議論に発展した。
24年かけて築いたエコシステムは、技術的には負債を抱えている。PHPのプロセスモデルに由来するセキュリティの構造的問題はこの記事で述べた通りだ。しかしその負債の上に、59,000のプラグインと12,000のテーマ、何百万人もの開発者、そして数えきれないビジネスが乗っている。EmDashが「技術的に正しいアーキテクチャ」で挑むのは、この積み上げだ。
このブログがAstro製なので、EmDashがAstro 6.0ベースというだけで気になって調べた。プラグインサンドボックスの設計は筋が通っていて、WordPressが20年抱えてきた問題への回答としては説得力がある。v0.1.0でどこまで実用に耐えるかは別だが、気が向いたら触ってみたい。