ハンズオン:AIとブログを作って公開する
完成するもの
- 自分のパソコンで動くEmDashのブログ(公式のブログテンプレートのCloudflare版)
- 管理画面で書いて公開した1件の投稿
- Cloudflare Workersにデプロイされ、
workers.devのURLで表示されるブログ
ブログテンプレートには、投稿、固定ページ、執筆者、カテゴリー、タグ、検索、コメント、ウィジェット、RSSフィードが入っています。(公式「ブログを作る」)
所要時間
目安:60分
AIエージェントによる実測のあとに、この時間を更新します。
必要なもの
| 種類 | 必要なもの | 使う場面 |
|---|---|---|
| ツール | Node.js 22.16以上 | すべてのステップ |
| ツール | pnpm | すべてのステップ |
| ツール | ターミナル | コマンドの実行 |
| ツール | パスキーを登録できるブラウザ | 管理画面の初期設定 |
| ツール | 生成AIツール | ターミナルでコマンドを実行できるAIツール(Claude Code、Cursor、Codexなど)、またはチャット型のAI(ChatGPT、Claudeのチャットなど)。使い方の違いは「依頼文の使い方」で説明します |
| アカウント | Cloudflareアカウント | ステップ6以降(デプロイ)だけ |
ローカルで開発している間は、データベースとファイル置き場のローカル版が自分のパソコンで動きます。Cloudflareアカウントが必要になるのはデプロイのときだけです。(公式「ブログを作る」)
テンプレートの選び方
公式ドキュメントには、始め方が2つあります。
| 公式ページ | テンプレート | 作成コマンドの指定 | データベースとファイル置き場 |
|---|---|---|---|
| はじめてのEmDashサイト作成 | Starter(Node.js版) | --template node:starter --pm npm |
SQLiteとローカルのメディアストレージ |
| ブログを作る | ブログ(Cloudflare版) | --template cloudflare:blog --pm pnpm |
ローカル開発中はローカル版、デプロイ後はD1とR2 |
このハンズオンはCloudflareへのデプロイまで進めるため、公式「ブログを作る」が使うブログテンプレートのCloudflare版を使います。公式「Cloudflareへのデプロイ」も、EmDashのCloudflare用テンプレートから始める手順です。管理画面の初期設定と「変更を公開する」の操作は、公式「はじめてのEmDashサイト作成」の手順に沿って確認します。
手順の全体像
図のテキストを読む
flowchart TD
S0["0. Node.jsとpnpmを確認"] --> S1["1. ブログの雛形を作る"]
S1 --> S2["2. 開発サーバーを起動"]
S2 --> S3["3. 管理画面の初期設定"]
S3 --> S4["4. 最初の投稿を公開"]
S4 --> S5["5. 投稿ページとRSSを確認"]
S5 --> S6["6. Cloudflareにログイン"]
S6 --> S7["7. ビルドしてデプロイ"]
S7 --> S8["8. デプロイ先を確認"]
ステップ0〜5は自分のパソコンの中だけで進みます。ステップ6からCloudflareを使います。
依頼文の使い方
- 依頼文は、そのままコピーしてAIに貼り付けられる形にしています。
- AIツールによって、コマンドを実行する人が違います。依頼文はどちらの種類でも同じ文面で使えます。
- ターミナルでコマンドを実行できるAIツール(Claude Code、Cursor、Codexなど):依頼文を渡すと、AIがコマンドを実行します。
- チャット型のAI(ChatGPT、Claudeのチャットなど):AIが示したコマンドを、自分でターミナルに貼って実行します。
- どの依頼文にも「公式ドキュメントの現在の内容を確認してから答える」指示を入れています。AIが古い仕様で答えるのを防ぐためです。
ステップ
ステップ0:Node.jsとpnpmを確認する
node --version でNode.jsのバージョンを確認します。pnpmは公式「ブログを作る」の前提条件です。
ステップ1:ブログの雛形を作る
ブログテンプレートのCloudflare版から my-blog を作り、pnpmで依存パッケージをインストールします。作成ツールは、EMDASH_ENCRYPTION_KEY を書き込んだ .env ファイルも作ります。.env は、生成される .gitignore によってGitの管理対象から除外されます。
ステップ2:開発サーバーを起動する
プロジェクトのディレクトリに移動し、開発サーバーを起動します。ターミナルに表示されたローカルのURLを開き、続けて /_emdash/admin を開きます。
ステップ3:管理画面の初期設定を完了する
初めて管理画面を開くと、セットアップウィザードが表示されます。テンプレートのシードデータ(seed/seed.json)から、コンテンツモデルとサンプルコンテンツが作られます。最初に作ったユーザーは、必ず管理者になります。(公式「ブログを作る」「認証」)
- 「サイトをセットアップ」で「サイトタイトル」と、必要に応じて「キャッチフレーズ」を入力します。「サンプルコンテンツを含める(新しいサイトに推奨)」は選択したままにして、「続行」を選択します。
- 「アカウントを作成」で「メールアドレス」と、必要に応じて「名前」を入力し、「続行」を選択します。
- 「アカウントを保護」で、ブラウザに認証情報の確認画面が表示されたらパスキーを登録します。登録が終わったら「Open the dashboard」を選択します。
ステップ4:最初の投稿を公開する
管理画面で投稿を1件作り、下書きとして保存してから公開します。
- 管理画面のサイドバーで「Posts」を選択し、「新規追加」を選択します。
- タイトルを入力します。EmDashがタイトルからスラッグを提案します。公開URLを変えたい場合は編集します。
- 抜粋を入力し、「Content」のエディターで本文を書きます。
- メディアライブラリからアイキャッチ画像を選択するか、アップロードします。記事の中での画像の役割を説明する代替テキストを入力します。
- 設定パネルで、バイライン、カテゴリー、必要なタグを割り当てます。
- 「保存」を選択します。エントリーは下書きになり、エディターはそのエントリーの固定のURLで開き直します。
- 「プレビュー」を選択して投稿ページを確認します。エディターに戻り、下書きの準備ができたら「公開」を選択します。
ステップ5:投稿ページとRSSフィードを確認する
公開した投稿は、投稿ページ、トップページ、投稿一覧に表示されます。テンプレートは /rss.xml でRSSフィードも配信しています。
ステップ6:Cloudflareにログインする
デプロイの前に、WranglerをCloudflareアカウントで認証します。公式「Cloudflareへのデプロイ」の前提条件は、Cloudflareアカウント、依存パッケージのインストール済みのプロジェクト、Cloudflareで認証済みのWranglerの3つです。
ステップ7:ビルドしてデプロイする
ビルドとデプロイを1回実行します。初回のデプロイで、Wranglerは wrangler.jsonc に書かれた名前のD1データベースとR2バケットを作ります。以降のデプロイは、同じリソースにつながります。wrangler.jsonc の名前は変えずに使います。(公式「Cloudflareへのデプロイ」)
ステップ8:デプロイ先を確認する
公式「Cloudflareへのデプロイ」は、デプロイ後に次の4つを確認するよう説明しています。公開ページを1つ開く、/_emdash/admin にログインする、テスト用のメディアファイルをアップロードして取得する、スケジュール処理が pnpm wrangler tail に表示されることを確認する、の4つです。
デプロイ先は、ローカルとは別のデータベースです。管理画面に初めてアクセスすると、セットアップウィザードで管理者アカウントを作成します。パスキーはドメインごとに登録します。localhost:4321 用に登録したパスキーは、ほかのドメインでは使えません。(公式「認証」)
うまくいかないときの確認点
| 症状 | 確認すること | 公式ページ |
|---|---|---|
| 雛形の作成で、依存パッケージのインストールに失敗したと表示される | プロジェクトのディレクトリに移動して pnpm install を実行してから先に進みます |
ブログを作る |
| 公開したはずの投稿がサイトに表示されない | エディターの状態表示が「公開済み」になっているかを確認します。「下書き」や「予約済み」では表示されません | ブログを作る |
| ローカルで書いた投稿がデプロイ先にない | ローカルの開発用データベースの投稿は、デプロイしても本番にコピーされません | ブログを作る |
| デプロイ先で「D1 binding not found」と表示される | wrangler.jsonc のバインディング名と、astro.config.mjs の d1({ binding: "DB" }) の名前が一致しているかを確認します |
Cloudflareへのデプロイ(トラブルシューティング) |
| デプロイ先で「R2 binding not found」と表示される | wrangler.jsonc のバインディング名と、r2({ binding: "MEDIA" }) の名前が一致しているかを確認します |
Cloudflareへのデプロイ(トラブルシューティング) |
ビルド時に [emdash] Sandboxed plugins are disabled because wrangler.jsonc has no LOADER Worker Loader binding と表示される |
Workersの無料プランでは想定どおりの表示です。サンドボックス型プラグインを使う場合は、Workersの有料プランで LOADER のバインディングを有効にしてビルドし直します |
プラグインサンドボックス(トラブルシューティング) |
| デプロイ先でスキーマのエラーが出る | wrangler tail でWorkerのログを表示しながらエラーを再現し、元のメッセージを記録します。そのうえで、その出力を添えてissueを登録します |
Cloudflareへのデプロイ(トラブルシューティング) |
| デプロイ先の管理画面で「Passkey authentication failed」と表示される | パスキーはドメインごとに登録します。デプロイ先のドメイン用に新しいパスキーを登録します | 認証(トラブルシューティング) |
このほかの症状は「つまずきやすいポイント」にまとめています。
根拠にした公式ページ
- はじめてのEmDashサイト作成:https://docs.emdashcms.com/getting-started/
- ブログを作る:https://docs.emdashcms.com/guides/create-a-blog/
- Cloudflareへのデプロイ:https://docs.emdashcms.com/deployment/cloudflare/
- 認証:https://docs.emdashcms.com/guides/authentication/
- AIツール向けDocs MCP:https://docs.emdashcms.com/docs-mcp/
- プラグインサンドボックス:https://docs.emdashcms.com/deployment/plugin-sandbox/