設定參考

本頁內容

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, // Contributor
  },
  
  // 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, // Contributor
}

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

選用。 站台面向瀏覽器的公開 origin(scheme + host + 選用 port,無路徑)。

TLS 終止反向代理後方,Astro.url 會傳回內部位址(http://localhost:4321)而非公開位址(https://cms.example.com)。這會導致通行密鑰、CSRF origin 比對、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-*。為使用者存取的主機名稱(與 scheme)設定 security.allowedDomains。在 astro dev 中,新增相符的 vite.server.allowedHosts 以便 Vite 接受代理的 Host 標頭。

優先修正 allowedDomains(以及轉發的標頭);當重建的 URL 仍然偏離瀏覽器 origin 時(通常在前方終止 TLS 而上游請求保持 http:// 時),才使用 siteUrl

在 TLS 前方終止的情況下,將開發伺服器繫結到 loopback(astro dev --host 127.0.0.1)通常已足夠:代理在本地連線,而 siteUrl 與公開的 HTTPS origin 匹配。

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 匯入。

選項類型預設值說明
bindingstring來自 wrangler.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面向瀏覽器的公開 origin(回退至 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