設定リファレンス

このページ

EmDashは2つのファイルで設定されます:統合用のastro.config.mjsとコンテンツコレクション用のsrc/live.config.tsです。

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 (@emdash-cms/cloudflareからインポート)
database: d1({ binding: "DB" });

詳細についてはデータベースオプションを参照してください。

storage

必須。 メディアストレージアダプター設定。1つのアダプターを選択してください:

// ローカルファイルシステム (開発環境)
storage: local({
	directory: "./uploads",
	baseUrl: "/_emdash/api/media/file",
});

// R2バインディング (Cloudflare Workers)
storage: r2({
	binding: "MEDIA",
	publicUrl: "https://pub-xxxx.r2.dev", // オプション
});

// S3互換 (任意のプラットフォーム) — すべてのフィールドはS3_*環境変数から
storage: s3()

// または明示的な値を使用
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", // オプション、デフォルト: "auto"
	publicUrl: "https://cdn.example.com", // オプション
});

詳細についてはストレージオプションを参照してください。

plugins

オプション。 EmDashプラグインの配列。次の例は1つのプラグインを登録します:

import seoPlugin from "@emdash-cms/plugin-seo";

plugins: [seoPlugin()];

fonts

オプション。 管理UIのフォント設定。

デフォルトでは、EmDashはAstro Font APIを介してNoto Sansを読み込みます。フォントはビルド時にGoogleからダウンロードされ、セルフホストされるため、ランタイムCDNリクエストはありません。基本フォントはラテン文字、キリル文字、ギリシャ文字、デーバナーガリー文字、ベトナム文字をカバーしています。

追加の書記体系のサポートを追加するには、スクリプト名を渡します。次の例はアラビア語と日本語を追加します:

emdash({
  fonts: {
    scripts: ["arabic", "japanese"],
  },
})

利用可能なスクリプトは arabicarmenianbengalichinese-simplifiedchinese-traditionalchinese-hongkongdevanagariethiopicfarsigeorgiangujaratigurmukhihebrewjapanesekannadakhmerkoreanlaomalayalammyanmaroriyasinhalatamilteluguthai、および tibetanです。

各スクリプトはGoogle Fontsの対応するNoto Sansバリアントにマップされます(例:"arabic"はNoto Sans Arabicを読み込みます)。すべてのフォントフェイスは単一の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()のオプション:

オプションデフォルト説明
teamDomainstring必須Cloudflare Accessチームドメイン
audiencestringアプリケーションオーディエンス(AUD)タグ。WorkersではaudienceEnvVarを優先してください。
audienceEnvVarstring"CF_ACCESS_AUDIENCE"ランタイムでオーディエンスタグを読み取る環境変数
autoProvisionbooleantrue初回ログイン時にEmDashユーザーを作成
defaultRolenumber30roleMappingに一致しないユーザーのロールレベル(ユーザーロールを参照)
syncRolesbooleanfalseプロビジョニング時のみではなく、ログインごとにroleMappingを再適用
roleMappingobjectIdPグループ名を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を読み取ります。
  • atproto() — Atmosphereアカウントログイン(Blueskyおよびより広範なATプロトコルネットワーク)。環境変数は不要です。{ allowedDIDs, allowedHandles, defaultRole }を受け入れます。Atmosphereログインガイドを参照してください。

サードパーティパッケージは、同じAuthProviderDescriptor形式を使用して独自のプロバイダーを登録できます — ログインプロバイダーを参照してください。

siteUrl

オプション。 サイトの公開ブラウザ向けオリジン(スキーム + ホスト + オプションのポート、パスなし)。

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が実行時に設定されるコンテナデプロイメントに便利です。

マルチオリジンパスキー検証

siteUrlは単一の正規オリジンを定義します。同じEmDashデプロイメントが登録可能な親ドメインを共有する複数のホスト名(例:https://example.comhttps://preview.example.com)でアクセス可能な場合、パスキー検証はsiteUrlと正確に一致しないオリジンのアサーションを拒否します — WebAuthnは同じrpIdの下のサブドメイン間でパスキーが有効であることを許可しているにもかかわらず。

astro.config.mjsallowedOriginsまたはEMDASH_ALLOWED_ORIGINS環境変数を介して追加の受け入れられたオリジンを宣言します。正規のsiteUrlrpIdのソースのままです;ここにリストされたエントリは検証時に受け入れられます。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.allowedOriginsconfig.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ヘッダーを書き込む場合は、trustedProxyHeadersを設定して、EmDashのレート制限が共有の”unknown”キーの下ですべてのリクエストをバケット化する代わりに実際のクライアントIPを使用できるようにします。

次の設定は、リバースプロキシデプロイメントのためにallowedDomainsvite.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デバイスフロー)およびパブリックコメントエンドポイントで使用されます。

Cloudflareでは、リクエストに添付されたcfオブジェクトが自動的に使用されます — 通常、これを設定する必要はありません。nginx、Caddy、Traefik、Fly、Railwayなどの背後にあるセルフホストデプロイメントでは、プロキシが書き込むヘッダーにこれを設定して、レート制限がすべてのリクエストを”unknown”として扱う代わりに実際のクライアント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で拒否されます。

データベースアダプター

emdash/dbからアダプターをインポートします:

import { sqlite, libsql, postgres } from "emdash/db";

sqlite(config)

better-sqlite3を使用するSQLiteデータベース。次の例はローカルファイルに接続します:

オプション説明
urlstringfile:プレフィックス付きのファイルパス
sqlite({ url: "file:./data.db" });

libsql(config)

libSQLデータベース。次の例はリモートlibSQLデータベースに接続します:

オプション説明
urlstringデータベースURL
authTokenstring認証トークン(ローカルファイルではオプション)
libsql({
	url: process.env.LIBSQL_DATABASE_URL,
	authToken: process.env.LIBSQL_AUTH_TOKEN,
});

postgres(config)

接続プーリングを使用するPostgreSQLデータベース。

オプション説明
connectionStringstringPostgreSQL接続URL
hoststringデータベースホスト
portnumberデータベースポート
databasestringデータベース名
userstringデータベースユーザー
passwordstringデータベースパスワード
sslbooleanSSLを有効にする
pool.minnumber最小プールサイズ(デフォルト: 0)
pool.maxnumber最大プールサイズ(デフォルト: 10)

次の例は接続文字列で接続します:

postgres({ connectionString: process.env.DATABASE_URL });

d1(config)

Cloudflare D1データベース。@emdash-cms/cloudflareからインポートします。

オプションデフォルト説明
bindingstringwrangler.jsoncからのD1バインディング名
sessionstring"disabled"読み取りレプリケーションモード: "disabled""auto"、または"primary-first"
bookmarkCookiestring"__em_d1_bookmark"セッションブックマークのクッキー名

次の例は基本的なバインディングと読み取りレプリカを有効にしたものを示します:

// 基本
d1({ binding: "DB" });

// 読み取りレプリカを使用
d1({ binding: "DB", session: "auto" });

session"auto"または"primary-first"の場合、EmDashはD1 Sessions APIを使用して読み取りクエリを近くのレプリカにルーティングします。認証されたユーザーは、ブックマークベースの読み取り後の書き込み一貫性を取得します。詳細についてはデータベースオプション — 読み取りレプリカを参照してください。

ストレージアダプター

emdash/astroからlocals3をインポートします。r2アダプターは@emdash-cms/cloudflareからインポートされます:

import emdash, { local, s3 } from "emdash/astro";
import { r2 } from "@emdash-cms/cloudflare";

local(config)

ローカルファイルシステムストレージ。次の例はローカルディレクトリからアップロードを提供します:

オプション説明
directorystringディレクトリパス
baseUrlstringファイルを提供するベースURL
local({
	directory: "./uploads",
	baseUrl: "/_emdash/api/media/file",
});

r2(config)

Cloudflare R2バインディング。次の例は公開URLを持つR2バインディングを使用します:

オプション説明
bindingstringR2バインディング名
publicUrlstringオプションの公開URL
r2({
	binding: "MEDIA",
	publicUrl: "https://pub-xxxx.r2.dev",
});

s3(config?)

S3互換ストレージ。すべての設定フィールドはオプションです:s3({...})から省略されたフィールドは、 Nodeプロセスの起動時に対応するS3_*環境変数から解決されます。明示的な値は常に優先されます。

前提条件: プロジェクトに@aws-sdk/client-s3@aws-sdk/s3-request-presignerをインストールしてください。 EmDash coreはAWS SDKをバンドルしていません。詳細については ストレージオプション: S3互換ストレージを参照してください。

オプション説明
endpointstringS3エンドポイントURL(S3_ENDPOINT
bucketstringバケット名(S3_BUCKET
accessKeyIdstringアクセスキー(S3_ACCESS_KEY_ID
secretAccessKeystringシークレットキー(S3_SECRET_ACCESS_KEY
regionstringリージョン、デフォルト"auto"S3_REGION
publicUrlstringオプションのCDN URL(S3_PUBLIC_URL

次の例は、すべてのフィールドを環境から解決するか、設定と環境を混在させるか、すべてのフィールドを明示的に渡します:

// すべてのフィールドをS3_*環境変数から(Node コンテナデプロイメント)
s3()

// 混在: CDNを設定から、残りを環境から
s3({ publicUrl: "https://cdn.example.com" })

// すべて明示的
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では、シークレットと変数はfetchハンドラーのenvパラメータを介して公開され、 process.envを介しては公開されないため、S3_*環境変数は取得されません。 Workersデプロイメントはr2(config)アダプターを使用するか、 s3({...})に明示的な値を渡す必要があります。詳細については ストレージオプションを参照してください。

ライブコレクション

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_URLスキーマ同期用のリモートEmDash URL

次のコマンドで暗号化キーを生成します:

npx emdash secrets generate

package.json設定

テンプレートとサイトは、package.jsonemdashキーの下にオプションのメタデータを宣言できます:

{
	"emdash": {
		"label": "My Blog Template",
		"seed": ".emdash/seed.json",
		"url": "https://my-site.pages.dev"
	}
}
オプション説明
label表示用のテンプレート名
seedシードJSONファイルへのパス
urlスキーマ同期用のリモートURL

TypeScript設定

EmDashは.emdash/types.tsに型を生成します。tsconfig.jsonにパスエイリアスを追加します:

{
	"compilerOptions": {
		"paths": {
			"@emdash-cms/types": ["./.emdash/types.ts"]
		}
	}
}

次のコマンドで型を生成します:

npx emdash types