O EmDash é configurado através de dois arquivos: astro.config.mjs para a integração e src/live.config.ts para as coleções de conteúdo.
Integração Astro
Configure o EmDash como uma integração Astro em astro.config.mjs:
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: [],
}),
],
});
Opções de integração
database
Obrigatório. Configuração do adaptador de banco de dados:
database: sqlite({ url: "file:./data.db" });
database: postgres({ connectionString: process.env.DATABASE_URL });
database: libsql({ url: process.env.LIBSQL_DATABASE_URL, authToken: process.env.LIBSQL_AUTH_TOKEN });
database: d1({ binding: "DB" });
storage
Obrigatório. Configuração do adaptador de armazenamento de mídia:
storage: local({ directory: "./uploads", baseUrl: "/_emdash/api/media/file" });
storage: r2({ binding: "MEDIA", publicUrl: "https://pub-xxxx.r2.dev" });
storage: s3()
objectCache
Opcional. Armazena em cache os resultados de consultas de conteúdo e configuração em um armazenamento chave/valor:
import { kvCache } from "@emdash-cms/cloudflare";
objectCache: kvCache({ binding: "CACHE" });
import { memoryCache } from "emdash/astro";
objectCache: memoryCache();
plugins
Opcional. Array de plugins EmDash:
import seoPlugin from "@emdash-cms/plugin-seo";
plugins: [seoPlugin()];
fonts
Opcional. Configuração de fontes da interface de administração.
Por padrão, o EmDash carrega Noto Sans via a API de Fontes do Astro. As fontes são baixadas do Google no momento da compilação e auto-hospedadas.
Para adicionar suporte a sistemas de escrita adicionais, passe nomes de scripts:
emdash({
fonts: {
scripts: ["arabic", "japanese"],
},
})
Defina como false para desabilitar completamente a injeção de fontes:
emdash({ fonts: false })
auth
Opcional. Um adaptador de autenticação. O login integrado do EmDash usa passkeys; configurar auth os substitui por um provedor externo:
import { access } from "@emdash-cms/cloudflare";
emdash({
auth: access({
teamDomain: "myteam.cloudflareaccess.com",
audience: "your-app-audience-tag",
roleMapping: { Admins: 50, Editors: 40 },
}),
});
authProviders
Opcional. Um array de provedores de login conectáveis:
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()],
});
Provedores integrados:
github()— lêEMDASH_OAUTH_GITHUB_CLIENT_ID/EMDASH_OAUTH_GITHUB_CLIENT_SECRET.google()— lêEMDASH_OAUTH_GOOGLE_CLIENT_ID/EMDASH_OAUTH_GOOGLE_CLIENT_SECRET.atproto()— Login de conta Atmosphere. Sem variáveis de ambiente necessárias.
siteUrl
Opcional. A origem pública orientada ao navegador para o site (esquema + host + porta opcional, sem caminho).
Atrás de um proxy reverso que termina TLS, Astro.url retorna o endereço interno em vez do público. Defina siteUrl para corrigir passkeys, CSRF, redirects OAuth e todos os outros recursos dependentes de origem de uma vez.
emdash({
database: sqlite({ url: "file:./data.db" }),
storage: local({ directory: "./uploads", baseUrl: "/_emdash/api/media/file" }),
siteUrl: "https://cms.example.com",
});
Verificação de passkey multi-origem
Declare origens adicionais aceitas via allowedOrigins ou a variável de ambiente EMDASH_ALLOWED_ORIGINS:
emdash({
siteUrl: "https://example.com",
allowedOrigins: ["https://preview.example.com"],
})
Configuração de proxy reverso
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
Opcional. Headers para confiar na resolução de IP do cliente atrás de um proxy reverso:
emdash({
trustedProxyHeaders: ["x-real-ip"],
});
maxUploadSize
Opcional. Tamanho máximo permitido para upload de arquivos de mídia em bytes. Padrão 52_428_800 (50 MB):
emdash({
maxUploadSize: 100 * 1024 * 1024, // 100 MB
});
toolbar
Opcional. Controla como a barra de ferramentas do editor é entregue. Padrão "server".
| Valor | Comportamento |
|---|---|
"server" (padrão) | A barra de ferramentas é injetada do lado do servidor em cada resposta HTML para um editor autenticado. |
"client" | O HTML público é idêntico para cada visitante. Um pequeno script bootstrap mostra uma pílula “Edit”. |
false | Nunca renderizar a barra de ferramentas. |
experimental
Opcional. Recursos opt-in cujo comportamento pode mudar em uma versão menor.
experimental.registry
Opcional. Aponta os fluxos de navegação e instalação de plugins do dashboard admin para um registro de plugins federado.
emdash({
sandboxRunner: "@emdash-cms/sandbox-cloudflare",
experimental: {
registry: {
aggregatorUrl: "https://registry.emdashcms.com",
acceptLabelers: "did:plc:emdashverification",
policy: {
minimumReleaseAge: "48h",
minimumReleaseAgeExclude: ["did:plc:yourfirstpartydid"],
},
},
},
});
Adaptadores de banco de dados
import { sqlite, libsql, postgres } from "emdash/db";
sqlite(config)
| Opção | Tipo | Descrição |
|---|---|---|
url | string | Caminho do arquivo com prefixo file: |
libsql(config)
| Opção | Tipo | Descrição |
|---|---|---|
url | string | URL do banco de dados |
authToken | string | Token de auth (opcional para arquivos locais) |
postgres(config)
| Opção | Tipo | Descrição |
|---|---|---|
connectionString | string | URL de conexão PostgreSQL |
host | string | Host do banco de dados |
port | number | Porta do banco de dados |
database | string | Nome do banco de dados |
user | string | Usuário do banco de dados |
password | string | Senha do banco de dados |
ssl | boolean | Habilitar SSL |
pool.min | number | Tamanho mínimo do pool (padrão: 0) |
pool.max | number | Tamanho máximo do pool (padrão: 10) |
d1(config)
Cloudflare D1. Importar de @emdash-cms/cloudflare.
| Opção | Tipo | Padrão | Descrição |
|---|---|---|---|
binding | string | — | Nome do binding D1 de wrangler.jsonc |
session | string | "disabled" | Modo de replicação de leitura |
bookmarkCookie | string | "__em_d1_bookmark" | Nome do cookie para bookmarks de sessão |
Adaptadores de armazenamento
import emdash, { local, s3 } from "emdash/astro";
import { r2 } from "@emdash-cms/cloudflare";
local(config)
| Opção | Tipo | Descrição |
|---|---|---|
directory | string | Caminho do diretório |
baseUrl | string | URL base para servir arquivos |
r2(config)
| Opção | Tipo | Descrição |
|---|---|---|
binding | string | Nome do binding R2 |
publicUrl | string | URL pública opcional |
s3(config?)
Armazenamento compatível com S3. Todos os campos são opcionais.
Pré-requisito: instale @aws-sdk/client-s3 e @aws-sdk/s3-request-presigner.
| Opção | Tipo | Descrição |
|---|---|---|
endpoint | string | URL do endpoint S3 (S3_ENDPOINT) |
bucket | string | Nome do bucket (S3_BUCKET) |
accessKeyId | string | Chave de acesso (S3_ACCESS_KEY_ID) |
secretAccessKey | string | Chave secreta (S3_SECRET_ACCESS_KEY) |
region | string | Região, padrão "auto" (S3_REGION) |
publicUrl | string | URL CDN opcional (S3_PUBLIC_URL) |
Adaptadores de object cache
kvCache(config)
Backend Cloudflare KV.
kvCache({ binding: "CACHE", defaultTtl: 3600, revalidate: 1000, timeout: 2000, keyPrefix: "em" })
memoryCache(config?)
Backend em processo para Node.js.
memoryCache({ defaultTtl: 3600, revalidate: 1000, maxEntries: 1000, keyPrefix: "em" })
Coleções em tempo real
import { defineLiveCollection } from "astro:content";
import { emdashLoader } from "emdash/runtime";
export const collections = {
_emdash: defineLiveCollection({
loader: emdashLoader(),
}),
};
Variáveis de ambiente
| Variável | Descrição |
|---|---|
EMDASH_SITE_URL | Origem pública orientada ao navegador |
EMDASH_ALLOWED_ORIGINS | Origens adicionais aceitas pela verificação de passkey |
EMDASH_DATABASE_URL | Substituir URL do banco de dados |
EMDASH_ENCRYPTION_KEY | Chave para criptografar segredos de plugins em repouso |
EMDASH_PREVIEW_SECRET | Substituição opcional para o segredo HMAC de preview |
EMDASH_IP_SALT | Substituição opcional para o salt do hash IP do comentarista |
EMDASH_AUTH_SECRET | Legado. Usado como fonte de salt IP se definido. |
EMDASH_TURNSTILE_SECRET_KEY | Chave secreta do Cloudflare Turnstile |
EMDASH_URL | URL remota do EmDash para sincronização de schema |
npx emdash secrets generate
Configuração do package.json
{
"emdash": {
"label": "My Blog Template",
"seed": ".emdash/seed.json",
"url": "https://my-site.pages.dev"
}
}
Configuração TypeScript
{
"compilerOptions": {
"paths": {
"@emdash-cms/types": ["./.emdash/types.ts"]
}
}
}
npx emdash types