配置参考
EmDash 通过两个文件进行配置:astro.config.mjs 用于集成,src/live.config.ts 用于内容集合。
Astro 集成
Section titled “Astro 集成”将 EmDash 配置为 Astro 集成:
import { defineConfig } from "astro/config";import emdash, { local, r2, s3 } from "emdash/astro";import { sqlite, libsql, d1 } 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
Section titled “database”必需。 数据库适配器配置。
// SQLite (Node.js)database: sqlite({ url: "file:./data.db" });
// PostgreSQLdatabase: postgres({ connectionString: process.env.DATABASE_URL });
// libSQLdatabase: libsql({ url: process.env.LIBSQL_DATABASE_URL, authToken: process.env.LIBSQL_AUTH_TOKEN,});
// Cloudflare D1 (import from @emdash-cms/cloudflare)database: d1({ binding: "DB" });详情请参阅 数据库选项。
storage
Section titled “storage”必需。 媒体存储适配器配置。
// 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)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});详情请参阅 存储选项。
plugins
Section titled “plugins”可选。 EmDash 插件数组。
import seoPlugin from "@emdash-cms/plugin-seo";
plugins: [seoPlugin()];可选。 身份验证配置。
auth: { // Self-signup configuration selfSignup: { domains: ["example.com"], defaultRole: 20, // Contributor },
// OAuth providers oauth: { github: { clientId: process.env.GITHUB_CLIENT_ID, clientSecret: process.env.GITHUB_CLIENT_SECRET, }, google: { clientId: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, }, },
// Session configuration session: { maxAge: 30 * 24 * 60 * 60, // 30 days sliding: true, // Reset expiry on activity },
// OR use Cloudflare Access (exclusive mode) cloudflareAccess: { teamDomain: "myteam.cloudflareaccess.com", audience: "your-app-audience-tag", autoProvision: true, defaultRole: 30, syncRoles: false, roleMapping: { "Admins": 50, "Editors": 40, }, },}auth.selfSignup
Section titled “auth.selfSignup”允许用户在其电子邮件域名被允许的情况下自行注册。
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
domains | string[] | [] | 允许的电子邮件域名 |
defaultRole | number | 20 | 自注册用户的角色 |
selfSignup: { domains: ["example.com", "acme.org"], defaultRole: 20, // Contributor}auth.oauth
Section titled “auth.oauth”配置 OAuth 登录提供商。
oauth: { github: { clientId: process.env.GITHUB_CLIENT_ID, clientSecret: process.env.GITHUB_CLIENT_SECRET, }, google: { clientId: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, },}auth.session
Section titled “auth.session”会话配置。
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
maxAge | number | 2592000 (30天) | 会话生命周期(秒) |
sliding | boolean | true | 活动时重置过期时间 |
auth.cloudflareAccess
Section titled “auth.cloudflareAccess”使用 Cloudflare Access 作为身份验证提供商,替代通行密钥。
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
teamDomain | string | 必需 | 您的 Access 团队域名 |
audience | string | 必需 | 应用程序受众 (AUD) 标签 |
autoProvision | boolean | true | 首次登录时创建用户 |
defaultRole | number | 30 | 新用户的默认角色 |
syncRoles | boolean | false | 每次登录时更新角色 |
roleMapping | object | — | 映射 IdP 组到角色 |
passkeyPublicOrigin
Section titled “passkeyPublicOrigin”可选。 传递一个完整的面向浏览器的源(协议 + 主机 + 可选端口,无路径),以便 WebAuthn 的 rpId 和 origin 与用户浏览器在 clientData.origin 中发送的内容匹配。
默认情况下,通行密钥遵循 Astro.url / request.url。在TLS 终止反向代理后面,应用通常仍看到 http:// 的内部跳转,而浏览器标签页是 https://, 或重建的主机名与公共名称不匹配——这会破坏通行密钥验证。将 passkeyPublicOrigin 设置为用户在地址栏中输入的源(例如 https://cms.example.com 或 https://cms.example.com:8443)。
集成在加载时验证此值:它必须是具有 http: 或 https: 协议的有效 URL,并规范化为 origin。
emdash({ database: sqlite({ url: "file:./data.db" }), storage: local({ directory: "./uploads", baseUrl: "/_emdash/api/media/file", }), passkeyPublicOrigin: "https://cms.example.com",});反向代理和通行密钥
Section titled “反向代理和通行密钥”Astro 仅在公共主机被允许时反映 X-Forwarded-*。为您的用户访问的主机名(和协议)配置 security.allowedDomains。在 astro dev 中,添加匹配的 vite.server.allowedHosts,以便 Vite 接受代理的 Host 头。
优先修复 allowedDomains(和转发的头信息);当重建的 URL 仍然与浏览器源不同时,使用 passkeyPublicOrigin(通常在 TLS 在前端终止且上游请求保持 http:// 时发生)。
在前端使用 TLS 时,将开发服务器绑定到环回地址(astro dev --host 127.0.0.1)通常就足够了:代理在本地连接,而 passkeyPublicOrigin 匹配公共 HTTPS 源。
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", }), passkeyPublicOrigin: "https://cms.example.com", }), ],});数据库适配器
Section titled “数据库适配器”从 emdash/db 导入:
import { sqlite, libsql, postgres, d1 } from "emdash/db";sqlite(config)
Section titled “sqlite(config)”使用 better-sqlite3 的 SQLite 数据库。
| 选项 | 类型 | 描述 |
|---|---|---|
url | string | 带有 file: 前缀的文件路径 |
sqlite({ url: "file:./data.db" });libsql(config)
Section titled “libsql(config)”libSQL 数据库。
| 选项 | 类型 | 描述 |
|---|---|---|
url | string | 数据库 URL |
authToken | string | 身份验证令牌(本地文件可选) |
libsql({ url: process.env.LIBSQL_DATABASE_URL, authToken: process.env.LIBSQL_AUTH_TOKEN,});postgres(config)
Section titled “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) |
postgres({ connectionString: process.env.DATABASE_URL });d1(config)
Section titled “d1(config)”Cloudflare D1 数据库。从 @emdash-cms/cloudflare 导入。
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
binding | string | — | 来自 wrangler.jsonc 的 D1 绑定名称 |
session | string | "disabled" | 读取复制模式:"disabled"、"auto" 或 "primary-first" |
bookmarkCookie | string | "__ec_d1_bookmark" | 用于会话书签的 Cookie 名称 |
// Basicd1({ binding: "DB" });
// With read replicasd1({ binding: "DB", session: "auto" });当 session 为 "auto" 或 "primary-first" 时,EmDash 使用 D1 Sessions API 将读取查询路由到附近的副本。经过身份验证的用户获得基于书签的读写一致性。详情请参阅 数据库选项 — 读取副本。
从 emdash/astro 导入:
import emdash, { local, r2, s3 } from "emdash/astro";local(config)
Section titled “local(config)”本地文件系统存储。
| 选项 | 类型 | 描述 |
|---|---|---|
directory | string | 目录路径 |
baseUrl | string | 用于提供文件的基础 URL |
local({ directory: "./uploads", baseUrl: "/_emdash/api/media/file",});r2(config)
Section titled “r2(config)”Cloudflare R2 绑定。
| 选项 | 类型 | 描述 |
|---|---|---|
binding | string | R2 绑定名称 |
publicUrl | string | 可选的公共 URL |
r2({ binding: "MEDIA", publicUrl: "https://pub-xxxx.r2.dev",});s3(config)
Section titled “s3(config)”S3 兼容存储。
| 选项 | 类型 | 描述 |
|---|---|---|
endpoint | string | S3 端点 URL |
bucket | string | 存储桶名称 |
accessKeyId | string | 访问密钥 |
secretAccessKey | string | 秘密密钥 |
region | string | 区域(默认:"auto") |
publicUrl | string | 可选的 CDN URL |
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",});在 src/live.config.ts 中配置 EmDash 加载器:
import { defineLiveCollection } from "astro:content";import { emdashLoader } from "emdash/runtime";
export const collections = { _emdash: defineLiveCollection({ loader: emdashLoader(), }),};emdashLoader() 函数接受可选配置:
emdashLoader({ // Currently no options - reserved for future use});EmDash 遵循以下环境变量:
| 变量 | 描述 |
|---|---|
EMDASH_DATABASE_URL | 覆盖数据库 URL |
EMDASH_AUTH_SECRET | 用于通行密钥身份验证的密钥 |
EMDASH_PREVIEW_SECRET | 用于预览令牌生成的密钥 |
EMDASH_URL | 用于模式同步的远程 EmDash URL |
使用以下命令生成身份验证密钥:
npx emdash auth secretpackage.json 配置
Section titled “package.json 配置”package.json 中的可选配置:
{ "emdash": { "label": "My Blog Template", "description": "A clean, minimal blog template", "seed": ".emdash/seed.json", "url": "https://my-site.pages.dev", "preview": "https://emdash-blog.pages.dev" }}| 选项 | 描述 |
|---|---|
label | 用于显示的模板名称 |
description | 模板描述 |
seed | 种子 JSON 文件的路径 |
url | 用于模式同步的远程 URL |
preview | 用于模板预览的演示站点 URL |
TypeScript 配置
Section titled “TypeScript 配置”EmDash 在 .emdash/types.ts 中生成类型。添加到您的 tsconfig.json:
{ "compilerOptions": { "paths": { "@emdash-cms/types": ["./.emdash/types.ts"] } }}使用以下命令生成类型:
npx emdash types