EmDash の主な設定は astro.config.mjs にあり、src/live.config.ts はコンテンツローダーを登録します。デプロイ固有の値は環境変数から渡すこともできます。package.json の小さなメタデータブロックは、テンプレートのラベルと従来のローカル CLI フローをサポートします。
Astro インテグレーション
astro.config.mjs で EmDash を Astro インテグレーションとして設定します。
import { defineConfig } from "astro/config";
import emdash, { local, s3 } from "emdash/astro";
import { sqlite, libsql } from "emdash/db";
export default defineConfig({
integrations: [
emdash({
database: sqlite({ url: "file:./data.db" }),
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
}),
plugins: [],
}),
],
});
インテグレーションのオプション
database
必須。 データベースアダプターの設定です。アダプターを 1 つ選びます。
// SQLite (Node.js)
database: sqlite({ url: "file:./data.db" });
// PostgreSQL
database: postgres({ connectionString: process.env.DATABASE_URL });
// libSQL
database: libsql({
url: process.env.LIBSQL_DATABASE_URL,
authToken: process.env.LIBSQL_AUTH_TOKEN,
});
// Cloudflare D1 (import from @emdash-cms/cloudflare)
database: d1({ binding: "DB" });
詳細は データベースのオプション を参照してください。
migrations
任意。 EmDash の内部データベースマイグレーションを実行時にどう扱うかを制御します。このオプションを省略すると、既定値は { runtime: "auto" } です。
migrations: {
runtime: "check", // "auto" | "check" | "manual"
dev: "auto", // optional development override
}
auto は保留中のマイグレーションを確認して適用します。check は、実行中のビルドが把握している保留中のマイグレーションがある場合に 503 を返します(EmDash がインストールする画像エンドポイントへのリクエストを除く)。manual は実行時にマイグレーションのクエリを一切実行しません。EMDASH_MIGRATIONS_MODE は実際に有効な実行時モードを上書きします。check または manual を採用する前に、コアデータベースのマイグレーションを管理する を参照してください。
storage
任意。 メディアストレージアダプターの設定です。このオプションを省略すると、EmDash はファイルを ./.emdash/uploads に保存し、/_emdash/api/media/file 経由で配信します。既定のローカルディレクトリが適さない場合は、アダプターを選んでください。
// Local filesystem (development)
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
});
// R2 binding (Cloudflare Workers)
storage: r2({
binding: "MEDIA",
publicUrl: "https://pub-xxxx.r2.dev", // optional
});
// S3-compatible (any platform) — all fields from S3_* environment variables
storage: s3()
// Or with explicit values
storage: s3({
endpoint: "https://s3.amazonaws.com",
bucket: "my-bucket",
accessKeyId: process.env.S3_ACCESS_KEY_ID,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
region: "us-east-1", // optional, default: "auto"
publicUrl: "https://cdn.example.com", // optional
});
詳細は ストレージのオプション を参照してください。
images
任意。 保存済みメディアを Astro の画像最適化と統合するかどうかを制御します。既定値は true です。
有効にすると、EmDash は Astro の画像エンドポイントをラップし、<Image> と getImage() が設定済みのストレージアダプターから直接ソースのバイト列を読み取れるようにします。元のメディア URL が Cloudflare Access の背後にある場合でも動作します。ラップされたエンドポイントへのリクエストは EmDash のランタイム起動をスキップするため、それらのリクエストでは locals.emdash には storage のみが入り、サインイン済みユーザーの場合は db も加わります。locals.user は他の公開ルートと同様に設定されます。別の画像サービスがメディアを扱う場合や、EmDash のエンドポイントラッパーを通さずにすべての画像をレンダリングしたい場合は、images: false を設定してください。
emdash({
images: false,
});
mediaProviders
任意。 メディアライブラリにメディアサービスを追加します。ストレージを基盤とするローカルプロバイダーは自動的に引き続き利用できます。この配列の各ディスクリプターは、編集者がメディアを閲覧またはアップロードできる場所をもう 1 つ追加します。
次の例では Cloudflare Images と Cloudflare Stream を追加します。
import { cloudflareImages, cloudflareStream } from "@emdash-cms/cloudflare";
emdash({
mediaProviders: [cloudflareImages({}), cloudflareStream({})],
});
プロバイダーの認証情報は実行時に解決されます。上記の空の設定では、cloudflareImages(config) と cloudflareStream(config) のアダプターのセクションで説明している既定の Cloudflare 環境変数が使われます。バインディングとレンダリングの設定については、メディアライブラリ: メディアプロバイダー を参照してください。
objectCache
任意。 コンテンツと設定のクエリ結果をキー/バリューストアにキャッシュし、リクエストごとにデータベースへ問い合わせずに読み取りを処理できるようにします。省略した場合は無効です。アダプターを 1 つ選びます。
// Cloudflare KV (shared across all isolates)
import { kvCache } from "@emdash-cms/cloudflare";
objectCache: kvCache({ binding: "CACHE" });
// In-memory (Node.js / development)
import { memoryCache } from "emdash/astro";
objectCache: memoryCache();
設定とオプションについては オブジェクトキャッシュ を参照してください。
middleware.outer
任意。 EmDash のミドルウェアスタック全体の外側に Astro ミドルウェアモジュールを登録します。インテグレーションは Astro の order: "pre" で登録するため、src/middleware.ts に定義したミドルウェアよりも前に実行されます。キャッシュヒット時にランタイムとデータベースの初期化を避けたいリクエストゲートや完全なレスポンスキャッシュ、または EmDash の最終的な HTML に依存するレスポンスヘッダーに使用します。
emdash({
middleware: {
outer: "./src/outer-middleware.ts",
},
});
実行順序は次のとおりです。
- 外側のミドルウェアが
await next()まで実行されます。 - EmDash がランタイムとデータベースを初期化し、セットアップ、認証、リクエストコンテキストの各ミドルウェアを実行します。
- Astro のルートがレンダリングされます。
- EmDash がビジュアル編集用の HTML やセキュリティ/タイミングのヘッダーなど、レスポンスへの変更を適用します。
next()はその最終的なレスポンスとともに外側のミドルウェアへ解決されます。
next() を呼び出す前のミドルウェアでは、通常の Astro リクエストとプラットフォームの実行コンテキストは使えますが、locals.emdash、locals.user、データベース、およびリクエストスコープの EmDash の状態は使えません。早期に返した Response は EmDash を完全にスキップするため、必要なセキュリティヘッダーとキャッシュヘッダーをすべて含める必要があります。next() の解決後であれば、CSP の nonce の確定、本文全体のキャッシュ、Content-Length の設定を安全に行えます。ミドルウェアが本文を変更する場合は、既存の Content-Length ヘッダーを削除するか再計算してください。
このフックは、Node と Cloudflare のどちらでも Astro のミドルウェア API を使用します。次の最小限の Cloudflare Cache API の例は、匿名の HTML レスポンスだけをキャッシュし、EmDash の初期化前にヒットを返します。
import { waitUntil } from "cloudflare:workers";
import { defineMiddleware } from "astro:middleware";
export const onRequest = defineMiddleware(async ({ request }, next) => {
if (request.method !== "GET" || request.headers.has("cookie")) {
return next();
}
const cacheKey = new Request(request.url, { method: "GET" });
const cached = await caches.default.match(cacheKey);
if (cached) return cached;
const response = await next();
const isHtml = response.headers.get("content-type")?.includes("text/html");
const isPrivate = response.headers.get("cache-control")?.includes("no-store");
if (response.ok && isHtml && !isPrivate) {
waitUntil(caches.default.put(cacheKey, response.clone()));
}
return response;
});
Node では、Redis など Node 互換のキャッシュを使って同じ形のミドルウェアを書きます。キャッシュキーとバイパスルールには、レンダリング結果を変えるあらゆるリクエストのプロパティを含める必要があります。
playground
任意。 使い捨てのブラウザベースの EmDash プレイグラウンドが使うミドルウェアを有効にします。セッションごとに書き込み可能な Durable Object データベースを作成し、設定されたシードを適用し、通常の EmDash ミドルウェアが実行される前に訪問者を匿名の管理者としてサインインさせます。
import { playgroundDatabase } from "@emdash-cms/cloudflare";
emdash({
database: playgroundDatabase({ binding: "PLAYGROUND_DB" }),
playground: {
middlewareEntrypoint: "@emdash-cms/cloudflare/db/playground-middleware",
},
});
このモードには @emdash-cms/cloudflare と Durable Object バインディングが必要です。通常のセットアップおよび認証ミドルウェアをバイパスするため、本番の CMS ではなく、一時的なデモサイトにのみ使用してください。
plugins
任意。 Astro サイトと同じプロセスで実行されるプラグインの配列です。ネイティブプラグインはここに指定します。サンドボックス対応のプラグインも、プロセスへの完全なアクセスを許可して信頼でき、分離が不要な場合はここで実行できます。
次の例はネイティブプラグインを登録します。
import seoPlugin from "@emdash-cms/plugin-seo";
plugins: [seoPlugin()];
ネイティブプラグインはサーバーやフレームワークの API を直接使用できるため、パッケージがサンドボックス対応のプラグインエントリポイントも提供していない限り、sandboxed へ移すことはできません。開発とデプロイの違いについては、プラグイン形式を選ぶ を参照してください。
sandboxed
任意。 EmDash が宣言するプラグイン API を使い、分離されたランタイムで実行される、サンドボックス対応プラグインの配列です。ここにネイティブプラグインを置かないでください。ネイティブコードは、サンドボックスが提供しないプロセスやフレームワークへのアクセスに依存している可能性があります。
import thirdPartyPlugin from "third-party-emdash-plugin";
import { sandbox } from "@emdash-cms/cloudflare";
emdash({
sandboxed: [thirdPartyPlugin()],
sandboxRunner: sandbox(),
});
使用可能なサンドボックスランナーが設定されていない場合、サンドボックス化されたプラグインはスキップされます。Cloudflare と Node.js のランナー設定については、プラグインのサンドボックス を参照してください。
sandboxRunner
任意。 分離されたプラグインランタイムを起動するファクトリーのモジュール指定子です。sandboxed のプラグイン、およびマーケットプレイスまたはレジストリのプラグインに必要です。
Cloudflare Workers では sandbox() アダプターを使用します。
import { sandbox } from "@emdash-cms/cloudflare";
emdash({
sandboxRunner: sandbox(),
});
Node.js のデプロイでは、プラグインのサンドボックス: Node.js で説明している workerd ランナーモジュールを使用します。
sandbox
任意。 設定済みのサンドボックスランナーがプラグインを分離するかどうかを制御します。sandboxRunner が設定されていると、サンドボックスは有効になります。問題の原因がプラグイン自体にあるのか、そのサンドボックスランタイムにあるのかを切り分ける場合に限り、sandbox: false を設定してください。
emdash({
sandboxRunner: sandbox(),
sandbox: false,
});
false にすると、sandboxed で宣言されたプラグインとマーケットプレイスからインストールされたプラグインは、分離もリソース制限もなくメインのサーバープロセスで実行されます。診断が済んだらサンドボックスを元に戻してください。
registry
任意。 プラグインレジストリ のアグリゲーターとポリシーを設定します。明示的な値がない場合、sandboxRunner が設定されていて sandbox が false でなければ、EmDash は https://registry.emdashcms.com を使用します。
registry: false を設定すると、レジストリでの検索とレジストリからインストールされたプラグインが無効になります。一方で、sandboxed で宣言したプラグインと従来のマーケットプレイスのプラグイン向けに、サンドボックスランナーは引き続き利用できます。
emdash({
sandboxRunner: sandbox(),
registry: false,
});
レジストリサービスの URL を文字列で渡すか、サイトにモデレーションのソースやリリース経過期間のポリシーが必要な場合はオブジェクトを使用します。次の例はオブジェクト形式を使っています。
import { sandbox } from "@emdash-cms/cloudflare";
emdash({
sandboxRunner: sandbox(),
registry: {
aggregatorUrl: "https://registry.emdashcms.com",
acceptLabelers: "did:web:labels.emdashcms.com",
policy: {
minimumReleaseAge: "48h",
minimumReleaseAgeExclude: ["did:plc:yourfirstpartydid"],
},
},
});
| オプション | 型 | 説明 |
|---|---|---|
aggregatorUrl | string | レジストリサービスのベース URL。本番では HTTPS を使用してください。 |
acceptLabelers | string | リクエストが受け入れるモデレーションサービスの分散型識別子(DID)を、カンマ区切りで指定します(任意)。DID は Atmosphere アカウントの安定した識別子です。この設定でレジストリサービスのポリシーを上書きすることはできません。 |
policy.minimumReleaseAge | string | number | この経過期間より新しいリリースを保留します。期間の文字列("48h"、"7d")または秒数で指定します。 |
policy.minimumReleaseAgeExclude | string[] | 保留の対象外とする発行者の DID、または <did>/<plugin-slug> の組。 |
リリース経過期間のポリシーがパッケージの最初のリリースを対象外にするのは、レジストリが保持されたリリースが 1 つであると報告し、かつそのパッケージを継続的に観測したことを確認した場合に限られます。後から補完されたパッケージ、削除された以前のリリース、履歴の証拠の欠落がある場合は、保留が維持されます。発行者とパッケージの明示的な除外は、履歴にかかわらず適用されます。
インストールのワークフローと信頼モデルについては、プラグインレジストリ を参照してください。
marketplace
非推奨。 従来のマーケットプレイスからインストールしたプラグインを更新するために使うベース URL です。マーケットプレイスの閲覧と新規インストールは管理画面に表示されません。このオプションが設定されている間、既存のマーケットプレイスのプラグインは更新とアンインストールが引き続き可能です。
emdash({
marketplace: "https://marketplace.emdashcms.com",
sandboxRunner: sandbox(),
});
本番の URL は HTTPS を使用する必要があります。HTTP が受け入れられるのは、開発中の localhost と 127.0.0.1 のみです。すべてのマーケットプレイスのプラグインを置き換えるかアンインストールするまではこのオプションを残し、その後削除してください。完全な手順は マーケットプレイスから移行する に従ってください。
fonts
任意。 管理画面のフォント設定です。
既定では、EmDash は Astro Font API 経由で Noto Sans を読み込みます。フォントはビルド時に Google からダウンロードされてセルフホストされるため、実行時に CDN へのリクエストは発生しません。ベースフォントはラテン文字、キリル文字、ギリシャ文字、デーヴァナーガリー文字、ベトナム語の文字体系をカバーします。
追加の文字体系に対応するには、スクリプト名を渡します。次の例ではアラビア語と日本語を追加します。
emdash({
fonts: {
scripts: ["arabic", "japanese"],
},
})
利用可能なスクリプトは arabic、armenian、bengali、chinese-simplified、chinese-traditional、chinese-hongkong、devanagari、ethiopic、farsi、georgian、gujarati、gurmukhi、hebrew、japanese、kannada、khmer、korean、lao、malayalam、myanmar、oriya、sinhala、tamil、telugu、thai、tibetan です。
各スクリプトは、Google Fonts 上で対応する Noto Sans のバリアントにマップされます(たとえば "arabic" は Noto Sans Arabic を読み込みます)。すべてのフォントフェイスは 1 つの font-family 名を共有し、unicode-range を使用するため、ブラウザはページ上の文字に必要なファイルだけをダウンロードします。
false に設定すると、フォントの注入を完全に無効にしてシステムフォントを使用します。
emdash({
fonts: false,
})
管理画面の CSS は --font-emdash CSS 変数を使用します。これは上記のフォント設定によって自動的に設定されます。
auth
任意。 認証アダプターです。EmDash の組み込みログインはパスキーですが、auth を設定すると外部プロバイダーに置き換わります。Cloudflare Access アダプターの access() は @emdash-cms/cloudflare が提供します。
import { access } from "@emdash-cms/cloudflare";
emdash({
auth: access({
teamDomain: "myteam.cloudflareaccess.com",
audience: "your-app-audience-tag",
roleMapping: {
Admins: 50,
Editors: 40,
},
}),
});
access() のオプション:
| オプション | 型 | 既定値 | 説明 |
|---|---|---|---|
teamDomain | string | 必須 | Cloudflare Access のチームドメイン |
audience | string | — | アプリケーションの Audience (AUD) タグ。Workers では audienceEnvVar を推奨します。 |
audienceEnvVar | string | "CF_ACCESS_AUDIENCE" | 実行時に audience タグを読み取る環境変数 |
autoProvision | boolean | true | 初回ログイン時に EmDash ユーザーを作成します |
defaultRole | number | 30 | roleMapping に一致しないユーザーのロールレベル(ユーザーロール を参照) |
syncRoles | boolean | false | プロビジョニング時だけでなく、ログインのたびに roleMapping を再適用します |
syncName | boolean | true | 認証済みリクエストのたびに、ユーザー名を IdP の名前で置き換えます。false にすると、管理画面で名前を編集できます |
roleMapping | object | — | IdP のグループ名を EmDash のロールレベルにマップします。最初に一致したものが優先されます |
authProviders
任意。 プラグイン可能なログインプロバイダーの配列です(トップレベルで、auth と並んで指定します)。各エントリは、次に示すようにプロバイダーファクトリーを呼び出した結果です。
import { github } from "emdash/auth/providers/github";
import { google } from "emdash/auth/providers/google";
import { atproto } from "@emdash-cms/auth-atproto";
emdash({
authProviders: [github(), google(), atproto()],
});
組み込みプロバイダー:
github()—EMDASH_OAUTH_GITHUB_CLIENT_ID/EMDASH_OAUTH_GITHUB_CLIENT_SECRET(またはプレフィックスなしのフォールバック)を読み取ります。google()—EMDASH_OAUTH_GOOGLE_CLIENT_ID/EMDASH_OAUTH_GOOGLE_CLIENT_SECRETを読み取ります。microsoft()—EMDASH_OAUTH_MICROSOFT_CLIENT_ID/EMDASH_OAUTH_MICROSOFT_CLIENT_SECRET/EMDASH_OAUTH_MICROSOFT_TENANT_ID(またはプレフィックスなしのフォールバック)を読み取ります。{ emailVerified }を受け付けます。Microsoft を参照してください。atproto()— Atmosphere アカウントでのログイン(Bluesky および AT Protocol ネットワーク全体)。環境変数は不要です。{ allowedDIDs, allowedHandles, defaultRole }を受け付けます。Atmosphere ログインガイド を参照してください。
サードパーティのパッケージも、同じ AuthProviderDescriptor の形式を使って独自のプロバイダーを登録できます。ログインプロバイダー を参照してください。
mcp
任意。 /_emdash/api/mcp の Model Context Protocol (MCP) エンドポイントを有効にします。このエンドポイントは既定で有効で、ベアラートークンを必要とするため、有効にしても匿名アクセスは許可されません。
サイトで MCP エンドポイントを公開してはならない場合は、このオプションを false に設定します。
emdash({
mcp: false,
});
トークンの作成とクライアントの設定については、MCP サーバーリファレンス を参照してください。
siteUrl
サイトの、ブラウザから見える公開オリジンです(スキーム + ホスト + 任意のポート、パスなし)。サイトを Cloudflare Workers にデプロイする場合を除き、本番のセットアップを実行する前に設定してください。それ以外では、オリジンが設定されていない状態でセットアップを完了できるのは、ループバックの開発ホストだけです。
TLS を終端するリバースプロキシ の背後では、Astro.url が公開アドレス(https://cms.example.com)ではなく内部アドレス(http://localhost:4321)を返します。その結果、パスキー、CSRF のオリジン照合、OAuth のリダイレクト、ログインのリダイレクト、MCP のディスカバリー、スナップショットのエクスポート、サイトマップ、robots.txt、JSON-LD 構造化データが正しく動作しなくなります。siteUrl を設定すると、これらすべてを一度に解決できます。
インテグレーションはこの値を読み込み時に 検証 します。プロトコルが http: または https: の有効な URL である必要があり、オリジン に正規化されます(パスは削除されます)。
次の例は公開オリジンを設定します。
emdash({
database: sqlite({ url: "file:./data.db" }),
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
}),
siteUrl: "https://cms.example.com",
});
設定に siteUrl がない場合、EmDash は環境変数を EMDASH_SITE_URL、SITE_URL の順に確認します。公開 URL を実行時に設定するコンテナデプロイで便利です。
画像最適化は、これらの環境変数をビルド時に読み取ります。astro build の実行時に、Astro が許可する画像のオリジンを image.remotePatterns に記録するためです。EMDASH_SITE_URL または SITE_URL がランタイム環境でのみ設定されている場合(アプリの起動時に変数を注入するホストなど)、ローカルに保存されたメディアは最適化されずに配信されます。ビルド環境にも変数を設定するか、設定ファイルで siteUrl を指定してください。
ループバックでないホストで、どちらのソースも設定されていないと、セットアップは SITE_URL_REQUIRED で失敗します。これにより、認証されていない最初のセットアップリクエストが、後続の認証メールで使われるオリジンを選んでしまうことを防ぎます。Cloudflare Workers にデプロイした本番ビルドは例外です。Cloudflare は Worker にバインドされたホスト名宛てのリクエストだけをルーティングするため、セットアップは https:// と、セットアップが実行されているホスト名を記録します。同じビルドを wrangler dev、astro preview、または到達可能なアドレス上のセルフホストの workerd で提供する場合は、このような保証はありません。その場合は、先に siteUrl または EMDASH_SITE_URL を設定してください。
サインイン、招待、セルフサインアップ、復旧、コメント通知のメールに含まれるリンクは、次の順で最初に利用できるオリジンを使います。siteUrl またはその環境変数、Settings > General の Site URL、セットアップ時に記録されたオリジンです。使われるのは Site URL のオリジンだけで、ホストが localhost、127.0.0.1、[::1] でない限り https:// を使う必要があります。ctx.site.url はメール内リンクと同じオリジンを使い、ランタイムの起動時に読み取られます。siteUrl を設定せずにサイトを新しいドメインへ移した場合は、Change domain で Site URL を変更すると、メール内リンクがそのドメインを指すようになります。詳しくは 新しいドメインへ移行する を参照してください。サイトマップと robots.txt は順序が異なり、Site URL が siteUrl より優先されます。詳しくは robots.txt を参照してください。
Cloudflare Workers では、環境変数へのフォールバックは process.env を読み取ります。nodejs_compat を使うと、Cloudflare は互換性日付が 2025-04-01 以降の場合、既定で process.env を設定します。それより前の日付に固定しているプロジェクトでは、nodejs_compat_populate_process_env も追加する必要があります。
// wrangler.jsonc
{
"compatibility_date": "2026-02-24",
"compatibility_flags": ["nodejs_compat"],
"vars": { "EMDASH_SITE_URL": "https://cms.example.com" },
}
allowedOrigins
任意。 複数のホスト名で利用できるデプロイに対して、パスキーの検証が受け入れる追加のブラウザオリジンです。
siteUrl は 1 つの正規オリジンを定義します。同じ EmDash デプロイが、登録可能な親ドメインを共有する複数のホスト名(例: https://example.com と https://preview.example.com)でアクセスできる場合、パスキーの検証は、オリジンが siteUrl と完全に一致しないアサーションを拒否します。WebAuthn では、同じ rpId のもとでサブドメイン間でもパスキーを有効にできるにもかかわらずです。
追加で受け入れるオリジンは、astro.config.mjs の allowedOrigins または EMDASH_ALLOWED_ORIGINS 環境変数のどちらかで宣言します。正規の siteUrl は引き続き rpId の元になり、ここに列挙したエントリは検証時に受け入れられます。2 つのソースは実行時にマージされるため、設定では安定したオリジン(バージョン管理され、コードレビューされるもの)を宣言し、環境変数では環境固有の追加分(一時的な PR プレビューなど)を加えることができます。
次の例では、設定で追加のオリジンを 1 つ宣言します。
emdash({
siteUrl: "https://example.com",
allowedOrigins: ["https://preview.example.com"],
})
同等の値は環境変数から渡すこともできます。
EMDASH_SITE_URL=https://example.com
EMDASH_ALLOWED_ORIGINS=https://preview.example.com,https://staging.example.com
検証
EmDash は、ブラウザが決して受け入れない無効な設定を防ぐために、これらの値を検証します。
- 各エントリは、解析可能な
http:またはhttps:の URL で、末尾のドットがなく、ホスト名に空のラベルが含まれていてはなりません。 allowedOriginsが空でない場合、siteUrlが(どちらかのソースで)設定されている必要があり、IP リテラルであったり、末尾にドットのあるホスト名であったりしてはなりません。- 各オリジンは
siteUrlと同じホスト名か、そのサブドメインである必要があります。(WebAuthn では、rpIdがすべてのオリジンの登録可能なサフィックスであることが求められます。)
検証に失敗すると、EmDash config error in EMDASH_ALLOWED_ORIGINS: "https://other-site.com" is not a subdomain of siteUrl "https://example.com". Allowed origins must be the same hostname as siteUrl or a subdomain of it. のような、ソースが特定されたエラーが表示されます。
エラーがどこで表面化するかは、値をどこで宣言したかによって決まります。
- Astro の起動時:
config.allowedOriginsとconfig.siteUrlの両方がastro.config.mjsに由来する場合です。コード上のタイプミスはビルドの失敗として現れます。 - 最初のパスキー検証時: どちらかの値が
EMDASH_ALLOWED_ORIGINSまたはEMDASH_SITE_URLに由来する場合です。環境の不一致は、最初の検証試行時の 500 エラーとして現れます。
リバースプロキシの設定
Astro は、公開ホストが許可されている場合にのみ X-Forwarded-* を反映します。ユーザーがアクセスするホスト名(とスキーム)に対して security.allowedDomains を設定してください。astro dev では、Vite がプロキシの Host ヘッダーを受け入れるように、対応する vite.server.allowedHosts を追加します。
まず allowedDomains(と転送ヘッダー)を修正することを優先してください。再構築された URL がそれでもブラウザのオリジンと 食い違う 場合(TLS が前段で終端され、上流へのリクエストが http:// のままになる典型的なケース)に siteUrl を使います。
前段に TLS がある場合、開発サーバーをループバックにバインドする(astro dev --host 127.0.0.1)だけで十分なことがよくあります。プロキシはローカルで接続し、siteUrl は公開 HTTPS オリジンと一致します。
プロキシがクライアント IP ヘッダーを書き込む場合は、EmDash のレート制限が実際のクライアント IP を使えるように trustedProxyHeaders を設定してください。信頼できるクライアント IP がないと、認証のレート制限はスキップされ、すべての公開コメント投稿が 1 つのレート制限バケットを共有します(全訪問者合計で 10 分あたり 20 件のコメント)。
次の設定は、リバースプロキシ経由のデプロイ向けに allowedDomains、vite.server.allowedHosts、siteUrl をまとめて設定します。
import { defineConfig } from "astro/config";
import emdash, { local } from "emdash/astro";
import { sqlite } from "emdash/db";
export default defineConfig({
security: {
allowedDomains: [
{ hostname: "cms.example.com", protocol: "https" },
{ hostname: "cms.example.com", protocol: "http" },
],
},
vite: {
server: {
allowedHosts: ["cms.example.com"],
},
},
integrations: [
emdash({
database: sqlite({ url: "file:./data.db" }),
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
}),
siteUrl: "https://cms.example.com",
}),
],
});
trustedProxyHeaders
任意。 自分で管理しているリバースプロキシの背後で動作している場合に、クライアント IP の解決で信頼するヘッダーです。認証のレート制限(マジックリンク、サインアップ、パスキー、OAuth デバイスフロー、OAuth クライアント登録)と、公開コメントのエンドポイントで使用されます。
Cloudflare では、リクエストに付与された cf オブジェクトが自動的に使われるため、通常これを設定する 必要はありません。nginx、Caddy、Traefik、Fly、Railway などの背後にあるセルフホスト環境では、レート制限が実際のクライアント IP ごとにリクエストを数えられるように、プロキシが書き込むヘッダーをここに設定してください。
次の例は、nginx、Caddy、Traefik が設定する x-real-ip ヘッダーを信頼します。
emdash({
database: sqlite({ url: "file:./data.db" }),
trustedProxyHeaders: ["x-real-ip"],
});
ヘッダーは順番に試されます。*-forwarded-for に一致する値はカンマ区切りのリストとして解析され、最初のエントリが使われます。次の例は Fly.io のヘッダーを優先し、なければ x-forwarded-for にフォールバックします。
emdash({
trustedProxyHeaders: ["fly-client-ip", "x-forwarded-for"],
});
設定に指定がない場合、EmDash は EMDASH_TRUSTED_PROXY_HEADERS 環境変数(カンマ区切り)を読み取ります。設定で空の配列を明示した場合は、環境変数より優先されます。
maxUploadSize
任意。 メディアファイルのアップロードで許可される最大サイズ(バイト単位)です。直接のマルチパートアップロードと署名付き URL アップロードの両方に適用されます。既定値は 52_428_800(50 MB)です。次の例では上限を 100 MB に引き上げます。
emdash({
database: sqlite({ url: "file:./data.db" }),
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
}),
maxUploadSize: 100 * 1024 * 1024, // 100 MB
});
| 値 | 説明 |
|---|---|
number(バイト) | 正の有限整数である必要があります |
| 省略 | 既定は 50 MB です |
設定された上限を超えるアップロードは、直接アップロードのパスでは 413 Payload Too Large レスポンス、署名付き URL のパスでは 400 Validation Error で拒否されます。
admin
任意。 管理画面の EmDash ブランディングを置き換え、ビルドに含める管理画面の言語を制限します。ブランディングの値は、公開サイトのタイトル、ロゴ、ファビコンには影響しません。
emdash({
admin: {
logo: "/images/agency-logo.webp",
siteName: "Agency CMS",
footerLabel: "AgencyX",
favicon: "/favicon.ico",
},
});
| オプション | 型 | 説明 |
|---|---|---|
logo | string | ログインページとサイドバーに表示するロゴの URL またはパス |
siteName | string | サイドバーのヘッダーとブラウザのタイトルに表示される名前 |
footerLabel | string | false | サイドバーのバージョン横に表示するラベル。既定は "EmDash"、false で非表示 |
favicon | string | 管理ページ用のファビコンの URL またはパス |
locales | string[] | 含める管理画面の言語(例: ["en", "de"])。それ以外の言語のカタログは管理画面のバンドルから除外され、言語切り替えには一覧にある言語だけが表示されます。優先言語が一覧にないユーザーには英語が表示されます。en はフォールバックとして常に含まれ、省略しても追加されるため、admin: { locales: ["en-GB"] } では英語とイギリス英語の両方が提供されます。不明なコードを指定するとビルドが失敗し、エラーに利用可能なコードが一覧表示されます。 |
updateCheck
任意。 管理ダッシュボードのコア更新通知を制御します。既定値は true です。
有効にすると、EmDash は公開 npm レジストリで公開済みの emdash リリースを確認し(最大でも 1 日 1 回、リクエストの速度を落とさないようレスポンスの後に遅延実行されます)、より新しいバージョンがある場合に管理ダッシュボードに閉じられるバナーを表示します。バナーを閉じると、そのバージョンについては非表示になり、さらに新しいバージョンが利用可能になると再び表示されます。
バナーには、公開から少なくとも 24 時間経過した最新の安定版リリースが表示されるため、リリースは公開の 1 日後に通知されます。pnpm の minimumReleaseAge など、パッケージマネージャーのリリース経過期間ポリシーに合わせるには、minimumReleaseAge に期間の文字列("48h"、"7d")または秒数を設定します。"7d" の場合、バナーには公開から 1 週間以上経過した最新のリリースが表示されます。
emdash({
updateCheck: { minimumReleaseAge: "7d" },
})
このチェックは https://registry.npmjs.org/emdash への単純な GET で、サイトのデータは一切送信しません。外向きのインターネットアクセスがないデプロイでは、バナーが表示されないだけです。チェックを完全に無効にするには false に設定します。
emdash({
updateCheck: false,
})
バナーは情報提供のみです。EmDash の更新とは、プロジェクトの emdash パッケージのバージョンを上げて再デプロイすることであり、管理画面からそれを実行することはできません(また、すべきでもありません)。
toolbar
任意。 エディターのツールバー(公開ページ上の浮動ピル)の配信方法を制御します。既定値は "server" です。
| 値 | 動作 |
|---|---|
"server"(既定) | 認証済みのエディター向けにレンダリングされるすべての HTML レスポンスに、サーバー側でツールバーが注入されます。 |
"client" | 公開 HTML はすべての訪問者で同一です。ごく小さなブートストラップスクリプトが、管理画面にログインしたことのあるブラウザに「Edit」ピルを表示します。クリックするとセッションを検証し、_edit クエリパラメーター付きでページを再読み込みします。このページは常に新しくレンダリングされ(キャッシュされません)、完全なツールバーが付きます。 |
false | ツールバーもブートストラップスクリプトも一切レンダリングしません。 |
emdash({
toolbar: "client",
})
公開 HTML を共有キャッシュ(Cloudflare Cache Everything / Workers Cache、Fastly、Varnish など)経由で配信している場合は "client" を使用してください。サーバー側の注入では、匿名の訪問者が先にキャッシュを温めていると、公開サイトを閲覧しているエディターがツールバーなしのキャッシュ済み匿名バリアントを受け取るため、ツールバーはキャッシュの状態によって現れたり消えたりします。クライアントモードでは、共有可能な HTML にセッション固有のものは何も注入されないため、キャッシュは完全に有効なままで、ツールバーも確実に表示されます。
"client" モードに関する注意:
- ログアウト状態の訪問者が共有された
?_editURL を開くと、正規 URL にリダイレクトされるため、このパラメーターが下書きを漏らしたり、ページの内容で余分なキャッシュエントリを温めたりすることはありません。 - 「ログイン済み」のシグナルは、管理画面が設定する秘密ではない
localStorageのフラグです。ピルは編集ビューに入る前に実際のセッションを検証します。 - ブートストラップは小さなインライン
<script>です。サイトが'unsafe-inline'なしの厳格なContent-Security-Policyを送信している場合は、そのハッシュを追加してください。サーバー側で注入されるツールバーでも同様です。 - EmDash はセッション固有のものを何も注入しません。ただし、自分のテンプレートが
Astro.locals.userで分岐している場合(ログインユーザー向けの「Admin」ナビゲーションリンクなど)、その差異は HTML に残り、依然としてキャッシュを分断します。
どのモードでも、ツールバーはブラウザ上の × ボタンで閉じることができます(ブラウザごと、次にエディターが管理画面を開くまで)。プレビューと編集モードのレスポンスは、常に Cache-Control: private, no-store 付きでサーバー側でレンダリングされます。
データベースアダプター
アダプターは emdash/db からインポートします。
import { sqlite, libsql, postgres } from "emdash/db";
sqlite(config)
Node.js の組み込みデータベースドライバーを使用する SQLite データベースです。次の例はローカルファイルに接続します。
| オプション | 型 | 説明 |
|---|---|---|
url | string | file: プレフィックス付きのファイルパス |
sqlite({ url: "file:./data.db" });
libsql(config)
libSQL データベースです。次の例はリモートの libSQL データベースに接続します。
| オプション | 型 | 説明 |
|---|---|---|
url | string | データベース URL |
authToken | string | 実行時の認証トークン(ローカルファイルでは任意) |
migrationAuthTokenEnv | string | マイグレーショントークンの変数名(既定は TURSO_AUTH_TOKEN) |
libsql({
url: process.env.LIBSQL_DATABASE_URL,
authToken: process.env.LIBSQL_AUTH_TOKEN,
});
postgres(config)
コネクションプーリング付きの PostgreSQL データベースです。
| オプション | 型 | 説明 |
|---|---|---|
connectionString | string | PostgreSQL の接続 URL |
host | string | データベースのホスト |
port | number | データベースのポート |
database | string | データベース名 |
user | string | データベースのユーザー |
password | string | データベースのパスワード |
ssl | boolean | SSL を有効にします |
pool.min | number | プールの最小サイズ(既定: 0) |
pool.max | number | プールの最大サイズ(既定: 10) |
pool.connectionTimeoutMillis | number | 接続の最大待機時間(pg の既定: 0、タイムアウトなし) |
pool.idleTimeoutMillis | number | アイドルクライアントの存続時間(pg の既定: 10,000 ms) |
migrationConnectionStringEnv | string | マイグレーション用接続文字列の変数名(既定は DATABASE_URL) |
次の例は接続文字列を使って接続します。
postgres({ connectionString: process.env.DATABASE_URL });
d1(config)
Cloudflare D1 データベースです。@emdash-cms/cloudflare からインポートします。
| オプション | 型 | 既定値 | 説明 |
|---|---|---|---|
binding | string | — | wrangler.jsonc の D1 バインディング名 |
session | string | "disabled" | 読み取りレプリケーションのモード: "disabled"、"auto"、"primary-first" |
bookmarkCookie | string | "__em_d1_bookmark" | セッションブックマーク用の Cookie 名 |
coalesce | boolean | false | 同じイベントループのターンでの同時読み取りをまとめます。"disabled" 以外のセッションモードが必要です |
次の例は、基本的なバインディングと、読み取りレプリカを有効にしたバインディングを示します。
// Basic
d1({ binding: "DB" });
// With read replicas
d1({ binding: "DB", session: "auto" });
session が "auto" または "primary-first" の場合、EmDash は D1 Sessions API を使って読み取りクエリを近くのレプリカにルーティングします。認証済みユーザーは、ブックマークに基づく read-your-writes 一貫性を得られます。詳細は データベースのオプション — 読み取りレプリカ を参照してください。
hyperdrive(config?)
Cloudflare Hyperdrive バインディング経由の PostgreSQL です。このアダプターは @emdash-cms/cloudflare からインポートします。
| オプション | 型 | 既定値 | 説明 |
|---|---|---|---|
binding | string | "HYPERDRIVE" | クエリキャッシュを無効にしたプライマリの Hyperdrive バインディング |
cachedBinding | string | — | 匿名の公開読み取り用に任意で追加する、キャッシュ有効の 2 つ目のバインディング |
preferUncachedAfterWriteMs | number | 60_000 | cachedBinding が設定されている場合に、コンテンツの書き込み後、公開読み取りがプライマリを使用する期間 |
migrationConnectionStringEnv | string | プライマリバインディングから導出 | emdash migrate が使用する、PostgreSQL への直接 URL を含む環境変数 |
max | number | 5 | 1 つの Worker アイソレートから Hyperdrive への最大接続数 |
次の例は、認証済みリクエストと書き込みをキャッシュなしのバインディング経由にし、匿名の公開読み取りはキャッシュありのバインディングを使えるようにします。
hyperdrive({
binding: "HYPERDRIVE",
cachedBinding: "HYPERDRIVE_CACHED",
preferUncachedAfterWriteMs: 60_000,
});
2 つのバインディングは同じデータベースを指している必要があります。pg バージョン 8.16.3 以降をインストールし、nodejs_compat 互換性フラグを有効にし、デプロイのマイグレーション用にデータベースへの直接 URL を設定してください。Worker とマイグレーションの完全な設定については、データベースのオプション: Hyperdrive を参照してください。
durableObjects(config)
CMS を、SQLite を基盤とする 1 つの Durable Object に保存します。このアダプターは @emdash-cms/cloudflare からインポートします。
| オプション | 型 | 既定値 | 説明 |
|---|---|---|---|
binding | string | 必須 | EmDashDB クラス用の Durable Object 名前空間バインディング |
name | string | "emdash" | シングルトンオブジェクトの名前。1 つのバインディングの背後で複数のデータベースを分離する場合にのみ変更します |
session | string | "disabled" | "auto" は匿名の読み取りをレプリカに、書き込みをプライマリにルーティングします |
bookmarkCookie | string | "__em_do_bookmark" | "auto" モードで read-your-writes 一貫性のために使われる Cookie |
durableObjects({ binding: "DB_DO", session: "auto" });
レプリカへのルーティングには、experimental と replica_routing の互換性フラグに加えて、wrangler.jsonc の Durable Object クラスとマイグレーションのエントリが必要です。
previewDatabase(config)
プレビューセッションごとに、分離されたスナップショットデータベースを Durable Object 内に 1 つ作成します。唯一のオプションは、必須の binding 名です。
previewDatabase({ binding: "PREVIEW_DB" });
このアダプターはプレビュー用のインフラのためのもので、本番サイトのプライマリデータベース用ではありません。
playgroundDatabase(config)
プレイグラウンドのセッションごとに、シード済みの書き込み可能なデータベースを Durable Object 内に 1 つ作成します。playground インテグレーションオプションと組み合わせて使用します。
playgroundDatabase({ binding: "PLAYGROUND_DB" });
必須の binding は、プレイグラウンドの Durable Object 名前空間を指定します。このアダプターは使い捨てのデモサイトにのみ使用してください。
ストレージアダプター
local と s3 は emdash/astro からインポートします。r2 アダプターは @emdash-cms/cloudflare からインポートします。
import emdash, { local, s3 } from "emdash/astro";
import { r2 } from "@emdash-cms/cloudflare";
local(config)
ローカルファイルシステムのストレージです。次の例は、ローカルディレクトリからアップロードを配信します。
| オプション | 型 | 説明 |
|---|---|---|
directory | string | ディレクトリのパス |
baseUrl | string | ファイル配信用のベース URL |
local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
});
r2(config)
Cloudflare R2 バインディングです。次の例は、公開 URL 付きの R2 バインディングを使用します。
| オプション | 型 | 説明 |
|---|---|---|
binding | string | R2 バインディング名 |
publicUrl | string | 任意の公開 URL |
r2({
binding: "MEDIA",
publicUrl: "https://pub-xxxx.r2.dev",
});
s3(config?)
S3 互換のストレージです。設定のフィールドはすべて任意です。s3({...}) で省略したフィールドは、Node プロセスの起動時に、対応する S3_* 環境変数から解決されます。明示した値は常に優先されます。
設定と環境変数の値がマージされた後、endpoint と bucket は必須です。いずれかの認証情報が設定されている場合は、accessKeyId と secretAccessKey の両方が必須です。値が欠けていると、MISSING_S3_CONFIG エラーコードで起動に失敗します。
前提条件: プロジェクトに @aws-sdk/client-s3 と @aws-sdk/s3-request-presigner をインストールしてください。EmDash のコアは AWS SDK を同梱していません。詳細は
ストレージのオプション: S3 互換ストレージ
を参照してください。
| オプション | 型 | 説明 |
|---|---|---|
endpoint | string | S3 エンドポイント URL(S3_ENDPOINT) |
bucket | string | バケット名(S3_BUCKET) |
accessKeyId | string | アクセスキー(S3_ACCESS_KEY_ID) |
secretAccessKey | string | シークレットキー(S3_SECRET_ACCESS_KEY) |
region | string | リージョン、既定は "auto"(S3_REGION) |
publicUrl | string | 任意の CDN URL(S3_PUBLIC_URL) |
次の例は、すべてのフィールドを環境変数から解決する場合、設定と環境変数を組み合わせる場合、すべてのフィールドを明示的に渡す場合を示します。
// All fields from S3_* environment variables (Node container deployments)
s3()
// Mix: CDN from config, rest from environment
s3({ publicUrl: "https://cdn.example.com" })
// All explicit
s3({
endpoint: "https://xxx.r2.cloudflarestorage.com",
bucket: "media",
accessKeyId: process.env.R2_ACCESS_KEY_ID,
secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
publicUrl: "https://cdn.example.com",
})
実行時の環境変数の解決は Node 専用の機能です。Cloudflare Workers では、シークレットと変数は process.env ではなく fetch ハンドラーの env パラメーター経由で公開されるため、S3_* 環境変数は読み取られません。Workers のデプロイでは、r2(config) アダプターを使うか、s3({...}) に明示的な値を渡してください。詳細は
ストレージのオプション を参照してください。
オブジェクトキャッシュのアダプター
これらのいずれかを objectCache オプションに渡します。
kvCache(config)
すべてのアイソレートで共有される Cloudflare KV バックエンドです。@emdash-cms/cloudflare からインポートします。
kvCache({
binding: "CACHE", // KV binding name (required)
defaultTtl: 3600, // entry TTL in seconds (optional, KV minimum 60)
revalidate: 1000, // cross-isolate staleness window in ms (optional)
timeout: 2000, // per-op timeout in ms before a miss (optional, 0 disables)
keyPrefix: "em", // cache key prefix (optional)
})
memoryCache(config?)
Node.js と開発向けのインプロセスバックエンドです。emdash/astro からインポートします。
memoryCache({
defaultTtl: 3600, // entry TTL in seconds (optional)
revalidate: 1000, // staleness window in ms (optional)
maxEntries: 1000, // max cached keys before eviction (optional)
keyPrefix: "em", // cache key prefix (optional)
})
設定と動作については オブジェクトキャッシュ を参照してください。
認証とサンドボックスのアダプター
これらのアダプターは、auth と sandboxRunner のインテグレーションオプション用の値を返します。
access(config)
組み込みのパスキーログインを Cloudflare Access 認証に置き換えます。@emdash-cms/cloudflare からインポートし、その結果を auth に渡します。
import { access } from "@emdash-cms/cloudflare";
emdash({
auth: access({
teamDomain: "myteam.cloudflareaccess.com",
audienceEnvVar: "CF_ACCESS_AUDIENCE",
}),
});
teamDomain は必須です。このアダプターは、アプリケーションの audience を audience から、または audienceEnvVar で指定された変数から読み取れます。また、autoProvision、defaultRole、syncRoles、syncName、roleMapping も受け付けます。これらの既定値、ロールの動作、名前の同期は、auth オプションで説明しています。
sandbox()
プラグインのサンドボックスランナーとして Cloudflare Worker Loader を選択します。@emdash-cms/cloudflare からインポートし、その戻り値を sandboxRunner に渡します。
import { sandbox } from "@emdash-cms/cloudflare";
emdash({
sandboxRunner: sandbox(),
});
サイトには、Worker Loader バインディングとプラグインブリッジのエントリポイントも必要です。これらのデプロイ設定については、プラグインのサンドボックス: Cloudflare Workers を参照してください。
メディアプロバイダーのアダプター
メディアプロバイダーのディスクリプターを mediaProviders に渡します。組み込みの 2 つの Cloudflare プロバイダーは、どちらも @emdash-cms/cloudflare からインポートします。
以下の各 *EnvVar オプションは環境変数の名前を指定します。プロバイダーは、その名前の Cloudflare Workers バインディング、次に Node アダプターの process.env の順に読み取ります。対応する直接のオプション(accountId、accountHash、apiToken)は、常にこの両方より優先されます。
cloudflareImages(config)
画像アセットの閲覧、アップロード、削除、配信のために Cloudflare Images を追加します。
| オプション | 型 | 既定値 | 説明 |
|---|---|---|---|
accountId | string | CF_ACCOUNT_ID から | Cloudflare アカウント ID |
accountIdEnvVar | string | "CF_ACCOUNT_ID" | accountId を省略した場合に使用する変数 |
accountHash | string | CF_IMAGES_ACCOUNT_HASH から | 配信 URL で使われるアカウントハッシュ |
accountHashEnvVar | string | "CF_IMAGES_ACCOUNT_HASH" | accountHash を省略した場合に使用する変数 |
apiToken | string | CF_IMAGES_TOKEN から | Cloudflare Images の読み取りと編集の権限を持つトークン |
apiTokenEnvVar | string | "CF_IMAGES_TOKEN" | apiToken を省略した場合に使用する変数 |
deliveryDomain | string | imagedelivery.net | 画像配信用のカスタムホスト名 |
defaultVariant | string | "public" | 表示に使用する画像バリアント |
mediaProviders: [cloudflareImages({ defaultVariant: "public" })];
cloudflareStream(config)
動画アセットの閲覧、検索、アップロード、削除、再生のために Cloudflare Stream を追加します。
| オプション | 型 | 既定値 | 説明 |
|---|---|---|---|
accountId | string | CF_ACCOUNT_ID から | Cloudflare アカウント ID |
accountIdEnvVar | string | "CF_ACCOUNT_ID" | accountId を省略した場合に使用する変数 |
apiToken | string | CF_STREAM_TOKEN から | Cloudflare Stream の読み取りと編集の権限を持つトークン |
apiTokenEnvVar | string | "CF_STREAM_TOKEN" | apiToken を省略した場合に使用する変数 |
customerSubdomain | string | Cloudflare の既定値 | Stream 配信用のカスタムホスト名 |
controls | boolean | true | プレーヤーのコントロールを表示します |
autoplay | boolean | false | 再生を自動的に開始します |
loop | boolean | false | 再生を繰り返します |
muted | boolean | false、autoplay の場合は true | 再生をミュートします |
mediaProviders: [cloudflareStream({ controls: true })];
必要なバインディングとレンダリング用コンポーネントについては、メディアライブラリ: メディアプロバイダー を参照してください。
ライブコレクション
src/live.config.ts で EmDash ローダーを設定します。
import { defineLiveCollection } from "astro:content";
import { emdashLoader } from "emdash/runtime";
export const collections = {
_emdash: defineLiveCollection({
loader: emdashLoader(),
}),
};
ローダーのオプション
emdashLoader() 関数は引数を取りません。
emdashLoader();
環境変数
EmDash は次の環境変数を参照します。
| 変数 | 説明 |
|---|---|
EMDASH_SITE_URL | ブラウザから見える公開オリジン(SITE_URL にフォールバック) |
EMDASH_ALLOWED_ORIGINS | パスキーの検証が受け入れる追加オリジンのカンマ区切りリスト(複数サブドメインのデプロイ向け)。 |
EMDASH_DATABASE_URL | データベース URL を上書きします |
EMDASH_ENCRYPTION_KEY | プラグインのシークレットを保存時に暗号化するためのキー。運用者が用意するもので、データベースには保存されません。 |
EMDASH_PREVIEW_SECRET | プレビューの HMAC シークレットの任意の上書き。未設定の場合、サイトごとの安定した値が生成されてデータベースに保存されます。 |
EMDASH_IP_SALT | コメント投稿者の IP ハッシュのソルトの任意の上書き。未設定の場合、サイトごとの安定した値が生成されてデータベースに保存されます。 |
EMDASH_AUTH_SECRET | 非推奨。設定されている場合は IP ソルトのソースとして使われます。既存のインストールでは、アップグレード後もコメント投稿者の IP ハッシュを安定させるため、これを維持してください。 |
EMDASH_TURNSTILE_SECRET_KEY | Cloudflare Turnstile のシークレットキー(TURNSTILE_SECRET_KEY にフォールバック)。設定すると、コメントの投稿には有効な Turnstile トークンが必要になります。<CommentForm> の turnstileSiteKey プロパティと組み合わせて使用してください。 |
EMDASH_URL | スキーマ同期用のリモート EmDash URL |
次のコマンドで暗号化キーを生成します。
npx emdash secrets generate
package.json の設定
テンプレートとサイトは、package.json の emdash キーの下に任意のメタデータを宣言できます。
{
"emdash": {
"label": "My Blog Template",
"schema": ".emdash/schema.sql",
"seed": ".emdash/seed.json"
}
}
| オプション | 説明 |
|---|---|
label | 表示用のテンプレート名 |
schema | emdash init が読み取る任意の SQL スキーマ |
seed | シード JSON ファイルへのパス |
TypeScript の設定
ローカル開発中、Astro インテグレーションはプロジェクトルートに emdash-env.d.ts を生成し、スキーマの変更後に更新します。このファイルは emdash モジュールを拡張するため、標準の getEmDashCollection() と getEmDashEntry() のインポートは、パスエイリアスなしでローカルコレクションのフィールドを推論します。
別のコマンド emdash types は、実行中のローカルまたはリモートのインスタンスからスキーマを取得し、既定で .emdash/types.ts に書き込みます。アプリケーションのコードがそのスタンドアロンの出力を直接インポートする場合にのみ、エイリアスを追加してください。
{
"compilerOptions": {
"paths": {
"@emdash-cms/types": ["./.emdash/types.ts"]
}
}
}
次のコマンドで、リモートスキーマのスタンドアロンの型を生成します。
npx emdash types