配置参考

本页内容

EmDash 通过两个文件进行配置:用于集成的 astro.config.mjs 和用于内容集合的 src/live.config.ts

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

必需。 数据库适配器配置。

// 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

必需。 媒体存储适配器配置。

// 本地文件系统(开发环境)
storage: local({
	directory: "./uploads",
	baseUrl: "/_emdash/api/media/file",
});

// R2 绑定(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
});

详情参见存储选项

plugins

可选。 EmDash 插件数组。

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

plugins: [seoPlugin()];

auth

可选。 认证配置。

auth: {
  // 自助注册配置
  selfSignup: {
    domains: ["example.com"],
    defaultRole: 20, // 贡献者
  },
  
  // 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,
    },
  },
  
  // 会话配置
  session: {
    maxAge: 30 * 24 * 60 * 60, // 30 天
    sliding: true, // 活动时重置过期时间
  },
  
  // 或使用 Cloudflare Access(排他模式)
  cloudflareAccess: {
    teamDomain: "myteam.cloudflareaccess.com",
    audience: "your-app-audience-tag",
    autoProvision: true,
    defaultRole: 30,
    syncRoles: false,
    roleMapping: {
      "Admins": 50,
      "Editors": 40,
    },
  },
}

auth.selfSignup

如果用户的邮箱域名在允许列表中,则允许用户自助注册。

选项类型默认值描述
domainsstring[][]允许的邮箱域名
defaultRolenumber20自助注册的角色
selfSignup: {
  domains: ["example.com", "acme.org"],
  defaultRole: 20, // 贡献者
}

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

会话配置。

选项类型默认值描述
maxAgenumber2592000(30 天)会话生命周期(秒)
slidingbooleantrue活动时重置过期时间

auth.cloudflareAccess

使用 Cloudflare Access 作为认证提供商,替代通行密钥。

选项类型默认值描述
teamDomainstring必填你的 Access 团队域名
audiencestring必填应用程序 Audience (AUD) 标签
autoProvisionbooleantrue首次登录时创建用户
defaultRolenumber30新用户的默认角色
syncRolesbooleanfalse每次登录时更新角色
roleMappingobject将 IdP 组映射到角色

siteUrl

可选。 站点面向浏览器的公共源(协议 + 主机 + 可选端口,不含路径)。

TLS 终止反向代理后面,Astro.url 返回内部地址(http://localhost:4321)而非公共地址(https://cms.example.com)。这会导致通行密钥、CSRF 源匹配、OAuth 重定向、登录重定向、MCP 发现、快照导出、sitemap、robots.txt 和 JSON-LD 结构化数据出错。设置 siteUrl 即可一次性修复所有这些问题。

集成在加载时会验证此值:它必须是带有 http:https: 协议的有效 URL,并被标准化为 origin(路径会被去除)。

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 仅在允许公共主机时才反映 X-Forwarded-*。为用户访问的主机名(和协议)配置 security.allowedDomains。在 astro dev 中,添加匹配的 vite.server.allowedHosts 使 Vite 接受代理的 Host 头。

优先修复 allowedDomains(和转发的头信息);当重建的 URL 仍然偏离浏览器源时(通常是 TLS 在前面终止而上游请求保持 http:// 的情况),使用 siteUrl

在有前端 TLS 的情况下,将开发服务器绑定到回环地址(astro dev --host 127.0.0.1)通常就够了:代理在本地连接,而 siteUrl 匹配公共 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",
			}),
			siteUrl: "https://cms.example.com",
		}),
	],
});

数据库适配器

emdash/db 导入:

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

sqlite(config)

使用 better-sqlite3 的 SQLite 数据库。

选项类型描述
urlstring带有 file: 前缀的文件路径
sqlite({ url: "file:./data.db" });

libsql(config)

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数据库密码
sslboolean启用 SSL
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"__ec_d1_bookmark"会话书签的 Cookie 名称
// 基础用法
d1({ binding: "DB" });

// 使用只读副本
d1({ binding: "DB", session: "auto" });

session"auto""primary-first" 时,EmDash 使用 D1 Sessions API 将读取查询路由到附近的副本。已认证用户可获得基于书签的”读己所写”一致性。详情参见数据库选项 — 只读副本

存储适配器

emdash/astro 导入:

import emdash, { local, r2, s3 } from "emdash/astro";

local(config)

本地文件系统存储。

选项类型描述
directorystring目录路径
baseUrlstring提供文件的基础 URL
local({
	directory: "./uploads",
	baseUrl: "/_emdash/api/media/file",
});

r2(config)

Cloudflare 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 核心不包含 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
// 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 (unchanged from before)
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 handler 的 env 参数暴露,而非 process.env,因此 S3_* 环境变量不会被读取。Workers 部署应使用 r2(config) 适配器,或向 s3({...}) 传入显式值。详情参见存储选项

Live Collections

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_DATABASE_URL覆盖数据库 URL
EMDASH_AUTH_SECRET通行密钥认证的密钥
EMDASH_PREVIEW_SECRET预览令牌生成的密钥
EMDASH_URL用于模式同步的远程 EmDash URL

使用以下命令生成认证密钥:

npx emdash auth secret

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 配置

EmDash 在 .emdash/types.ts 中生成类型。添加到 tsconfig.json

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

使用以下命令生成类型:

npx emdash types