EmDash se configura a través de dos archivos: astro.config.mjs para la integración y src/live.config.ts para las colecciones de contenido.
Integración Astro
Configura EmDash como una integración de Astro en 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: [],
}),
],
});
Opciones de integración
database
Requerido. Configuración del adaptador de base de datos. Elige un adaptador:
// 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 (importar desde @emdash-cms/cloudflare)
database: d1({ binding: "DB" });
Consulta Opciones de Base de Datos para más detalles.
storage
Requerido. Configuración del adaptador de almacenamiento de medios. Elige un adaptador:
// Sistema de archivos local (desarrollo)
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
});
// Binding R2 (Cloudflare Workers)
storage: r2({
binding: "MEDIA",
publicUrl: "https://pub-xxxx.r2.dev", // opcional
});
// Compatible con S3 (cualquier plataforma) — todos los campos desde variables de entorno S3_*
storage: s3()
// O con valores explícitos
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", // opcional, por defecto: "auto"
publicUrl: "https://cdn.example.com", // opcional
});
Consulta Opciones de Almacenamiento para más detalles.
objectCache
Opcional. Almacena en caché los resultados de consultas de contenido y configuración en un almacén key/value para que las lecturas se sirvan sin consultar la base de datos en cada solicitud. Deshabilitado cuando se omite. Elige un adaptador:
// Cloudflare KV (compartido entre todos los isolates)
import { kvCache } from "@emdash-cms/cloudflare";
objectCache: kvCache({ binding: "CACHE" });
// En memoria (Node.js / desarrollo)
import { memoryCache } from "emdash/astro";
objectCache: memoryCache();
Consulta Object Cache para configuración y opciones.
plugins
Opcional. Array de plugins de EmDash. El siguiente ejemplo registra un plugin:
import seoPlugin from "@emdash-cms/plugin-seo";
plugins: [seoPlugin()];
fonts
Opcional. Configuración de fuentes de la interfaz de administración.
Por defecto, EmDash carga Noto Sans a través de la API de Fuentes de Astro. Las fuentes se descargan de Google en tiempo de compilación y se auto-alojan, por lo que no hay solicitudes CDN en tiempo de ejecución. La fuente base cubre los scripts latino, cirílico, griego, devanagari y vietnamita.
Para agregar soporte para sistemas de escritura adicionales, pasa nombres de scripts. El siguiente ejemplo agrega árabe y japonés:
emdash({
fonts: {
scripts: ["arabic", "japanese"],
},
})
Los scripts disponibles son arabic, armenian, bengali, chinese-simplified, chinese-traditional, chinese-hongkong, devanagari, ethiopic, farsi, georgian, gujarati, gurmukhi, hebrew, japanese, kannada, khmer, korean, lao, malayalam, myanmar, oriya, sinhala, tamil, telugu, thai y tibetan.
Cada script se mapea a la variante correspondiente de Noto Sans en Google Fonts (ej. "arabic" carga Noto Sans Arabic). Todas las caras de fuente comparten un único nombre font-family y usan unicode-range para que el navegador solo descargue los archivos que necesita para los caracteres en la página.
Establece en false para deshabilitar completamente la inyección de fuentes y usar fuentes del sistema:
emdash({
fonts: false,
})
El CSS del administrador usa la variable CSS --font-emdash. Esta se establece automáticamente por la configuración de fuentes anterior.
auth
Opcional. Un adaptador de autenticación. El login incorporado de EmDash usa passkeys; configurar auth los reemplaza con un proveedor externo. El adaptador de Cloudflare Access, access(), es proporcionado por @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,
},
}),
});
Opciones para access():
| Opción | Tipo | Por defecto | Descripción |
|---|---|---|---|
teamDomain | string | requerido | Tu dominio de equipo de Cloudflare Access |
audience | string | — | Etiqueta Application Audience (AUD). En Workers, prefiere audienceEnvVar. |
audienceEnvVar | string | "CF_ACCESS_AUDIENCE" | Variable de entorno de donde leer la etiqueta de audiencia en tiempo de ejecución |
autoProvision | boolean | true | Crear un usuario EmDash en el primer login |
defaultRole | number | 30 | Nivel de rol para usuarios no mapeados por roleMapping (ver Roles de usuario) |
syncRoles | boolean | false | Reaplicar roleMapping en cada login en lugar de solo en el aprovisionamiento |
roleMapping | object | — | Mapear nombres de grupos IdP a niveles de rol EmDash; primer coincidencia gana |
authProviders
Opcional. Un array de proveedores de login conectables (nivel superior, junto a auth). Cada entrada es el resultado de llamar a una fábrica de proveedores, como se muestra a continuación:
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()],
});
Proveedores incorporados:
github()— leeEMDASH_OAUTH_GITHUB_CLIENT_ID/EMDASH_OAUTH_GITHUB_CLIENT_SECRET(o fallbacks sin prefijo).google()— leeEMDASH_OAUTH_GOOGLE_CLIENT_ID/EMDASH_OAUTH_GOOGLE_CLIENT_SECRET.atproto()— Login de cuenta Atmosphere (Bluesky y la red más amplia del protocolo AT). No se necesitan variables de entorno. Acepta{ allowedDIDs, allowedHandles, defaultRole }. Consulta la guía de login Atmosphere.
Los paquetes de terceros pueden registrar sus propios proveedores usando la misma forma AuthProviderDescriptor — ver Proveedores de Login.
siteUrl
Opcional. El origen público orientado al navegador para el sitio (esquema + host + puerto opcional, sin ruta).
Detrás de un proxy inverso que termina TLS, Astro.url devuelve la dirección interna (http://localhost:4321) en lugar de la pública (https://cms.example.com). Esto rompe passkeys, coincidencia de origen CSRF, redirecciones OAuth, redirecciones de login, descubrimiento MCP, exportaciones de snapshots, sitemap, robots.txt y datos estructurados JSON-LD. Establece siteUrl para corregir todo esto de una vez.
La integración valida este valor al cargar: debe ser una URL válida con protocolo http: o https: y se normaliza a origin (la ruta se elimina).
El siguiente ejemplo establece el origen público:
emdash({
database: sqlite({ url: "file:./data.db" }),
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
}),
siteUrl: "https://cms.example.com",
});
Cuando siteUrl no está establecido en la configuración, EmDash verifica variables de entorno en orden: EMDASH_SITE_URL, luego SITE_URL. Esto es útil para despliegues en contenedores donde la URL pública se establece en tiempo de ejecución.
En Cloudflare Workers, el fallback de variable de entorno lee process.env, que está vacío a menos que el flag de compatibilidad nodejs_compat_populate_process_env esté habilitado. Para usar la variable de entorno en lugar de la opción de configuración allí, establece ambos:
// wrangler.jsonc
{
"compatibility_flags": ["nodejs_compat", "nodejs_compat_populate_process_env"],
"vars": { "EMDASH_SITE_URL": "https://cms.example.com" },
}
Verificación de passkey multi-origen
siteUrl define un único origen canónico. Cuando el mismo despliegue de EmDash es accesible bajo varios nombres de host que comparten un dominio padre registrable (ej. https://example.com y https://preview.example.com), la verificación de passkey rechaza aserciones cuyo origen no coincide exactamente con siteUrl — aunque WebAuthn permite que los passkeys sean válidos entre subdominios bajo el mismo rpId.
Declara orígenes adicionales aceptados mediante allowedOrigins en astro.config.mjs o la variable de entorno EMDASH_ALLOWED_ORIGINS. El siteUrl canónico sigue siendo la fuente de rpId; las entradas listadas aquí son aceptadas en el momento de la verificación. Las dos fuentes se fusionan en tiempo de ejecución, para que la configuración pueda declarar los orígenes estables (versionados, revisados por código) mientras las variables de entorno agregan extras específicos del entorno (ej. vistas previas efímeras de PR).
El siguiente ejemplo declara un origen adicional en la configuración:
emdash({
siteUrl: "https://example.com",
allowedOrigins: ["https://preview.example.com"],
})
Los valores equivalentes también pueden venir de variables de entorno:
EMDASH_SITE_URL=https://example.com
EMDASH_ALLOWED_ORIGINS=https://preview.example.com,https://staging.example.com
Validación
EmDash valida estos para prevenir configuración muerta que el navegador nunca respetaría:
- Cada entrada debe ser una URL parseable
http:ohttps:sin punto final y sin etiquetas vacías en el nombre de host. - Cuando
allowedOriginsno está vacío,siteUrldebe estar establecido (de cualquier fuente) y no debe ser un literal IP o tener un nombre de host con punto final. - Cada origen debe ser el mismo nombre de host que
siteUrlo un subdominio de él. (WebAuthn requiere querpIdsea un sufijo registrable de cada origen.)
Cuando la validación falla, verás un error atribuido a la fuente como 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.
Dónde aparece el error depende de dónde se declaran los valores:
- Al iniciar Astro, cuando tanto
config.allowedOriginscomoconfig.siteUrlvienen deastro.config.mjs— los errores tipográficos en el código hacen fallar la compilación. - En la primera verificación de passkey, cuando cualquier valor viene de
EMDASH_ALLOWED_ORIGINSoEMDASH_SITE_URL— las discrepancias de entorno aparecen como 500s en el primer intento de verificación.
Configuración de proxy inverso
Astro solo refleja X-Forwarded-* cuando el host público está permitido. Configura security.allowedDomains para el nombre de host (y esquemas) que usan tus usuarios. En astro dev, agrega vite.server.allowedHosts coincidente para que Vite acepte el header Host del proxy.
Prefiere corregir allowedDomains (y headers reenviados) primero; usa siteUrl cuando la URL reconstruida aún diverge del origen del navegador (típico cuando TLS se termina delante y la solicitud upstream permanece en http://).
Con TLS delante, vincular el servidor de desarrollo a loopback (astro dev --host 127.0.0.1) suele ser suficiente: el proxy se conecta localmente mientras siteUrl coincide con el origen HTTPS público.
Si tu proxy escribe un header de IP del cliente, establece trustedProxyHeaders para que los límites de tasa de EmDash puedan usar la IP real del cliente en lugar de agrupar cada solicitud bajo una clave “unknown” compartida.
La siguiente configuración establece allowedDomains, vite.server.allowedHosts y siteUrl juntos para un despliegue con proxy inverso:
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 en los que confiar para la resolución de IP del cliente cuando se ejecuta detrás de un proxy inverso que controlas. Usado por los límites de tasa de auth (magic-link, registro, passkey, OAuth device flow) y el endpoint público de comentarios.
En Cloudflare se usa automáticamente el objeto cf adjunto a la solicitud — normalmente no necesitas establecer esto. En despliegues auto-alojados detrás de nginx, Caddy, Traefik, Fly, Railway o similares, establece esto al header que escribe tu proxy para que los límites de tasa puedan agrupar por IP real del cliente en lugar de tratar cada solicitud como “unknown”.
El siguiente ejemplo confía en el header x-real-ip establecido por nginx, Caddy o Traefik:
emdash({
database: sqlite({ url: "file:./data.db" }),
trustedProxyHeaders: ["x-real-ip"],
});
Los headers se prueban en orden. Los valores que coinciden con *-forwarded-for se parsean como listas separadas por comas y se usa la primera entrada. El siguiente ejemplo prefiere el header de Fly.io y recurre a x-forwarded-for:
emdash({
trustedProxyHeaders: ["fly-client-ip", "x-forwarded-for"],
});
Cuando no está establecido en la configuración, EmDash lee la variable de entorno EMDASH_TRUSTED_PROXY_HEADERS (separada por comas). Un array vacío explícito en la configuración anula la variable de entorno.
maxUploadSize
Opcional. Tamaño máximo permitido de carga de archivos multimedia en bytes. Se aplica tanto a cargas multipart directas como a cargas con URL firmada. Por defecto 52_428_800 (50 MB). El siguiente ejemplo eleva el límite a 100 MB:
emdash({
database: sqlite({ url: "file:./data.db" }),
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
}),
maxUploadSize: 100 * 1024 * 1024, // 100 MB
});
| Valor | Descripción |
|---|---|
number (bytes) | Debe ser un entero positivo finito |
| omitido | Por defecto 50 MB |
Las cargas que excedan el límite configurado se rechazan con una respuesta 413 Payload Too Large en la ruta de carga directa, o un 400 Validation Error en la ruta de URL firmada.
toolbar
Opcional. Controla cómo se entrega la barra de herramientas del editor (la píldora flotante en páginas públicas). Por defecto "server".
| Valor | Comportamiento |
|---|---|
"server" (predeterminado) | La barra de herramientas se inyecta del lado del servidor en cada respuesta HTML renderizada para un editor autenticado. |
"client" | El HTML público es idéntico para cada visitante. Un pequeño script bootstrap muestra una píldora “Edit” en navegadores que han iniciado sesión en el admin; al hacer clic verifica la sesión y recarga la página con un parámetro de consulta _edit, que siempre se renderiza fresco (nunca en caché) con la barra de herramientas completa. |
false | Nunca renderizar la barra de herramientas ni el script bootstrap. |
emdash({
toolbar: "client",
})
Usa "client" cuando tu HTML público se sirve a través de un caché compartido (Cloudflare Cache Everything / Workers Cache, Fastly, Varnish, …).
Notas sobre el modo "client":
- Los visitantes no autenticados que abren una URL compartida
?_editson redirigidos a la URL canónica, para que el parámetro no pueda filtrar borradores o crear entradas de caché adicionales con contenido de página. - La señal de “iniciado sesión” es un flag
localStorageno secreto establecido por el admin; la píldora verifica la sesión real antes de entrar a la vista de edición. - El bootstrap es un pequeño
<script>en línea. Si tu sitio envía unaContent-Security-Policyestricta sin'unsafe-inline', agrega un hash para él — lo mismo aplica a la barra de herramientas inyectada del servidor. - EmDash no inyecta nada específico de sesión — pero si tus propias plantillas se ramifican en
Astro.locals.user(ej. un enlace de nav “Admin” para usuarios autenticados), esa variación sigue en tu HTML y sigue fragmentando el caché.
En todos los modos, la barra de herramientas puede ser descartada en el navegador mediante su botón × (por navegador, hasta la próxima vez que un editor abra el admin). Las respuestas de vista previa y modo de edición siempre se renderizan del lado del servidor con Cache-Control: private, no-store.
experimental
Opcional. Características opt-in cuyo comportamiento o formato de datos puede cambiar, o ser eliminado, en una versión menor. Cada campo se habilita independientemente.
experimental.registry
Opcional. Apunta los flujos de navegación e instalación de plugins del dashboard de admin a un registro de plugins federado en lugar del marketplace central. Requiere sandboxRunner, porque los plugins del registro se ejecutan en sandbox.
Pasa una cadena de URL de agregador simple, o un objeto cuando necesites un etiquetador o una política de antigüedad de release. El siguiente ejemplo usa la forma de objeto:
emdash({
sandboxRunner: "@emdash-cms/sandbox-cloudflare",
experimental: {
registry: {
aggregatorUrl: "https://registry.emdashcms.com",
acceptLabelers: "did:plc:emdashverification",
policy: {
minimumReleaseAge: "48h",
minimumReleaseAgeExclude: ["did:plc:yourfirstpartydid"],
},
},
},
});
| Opción | Tipo | Descripción |
|---|---|---|
aggregatorUrl | string | Origen del agregador donde están montados los endpoints XRPC del registro. HTTPS en producción. |
acceptLabelers | string | DIDs de etiquetadores separados por comas reenviados al agregador para etiquetas de eliminación y verificación. |
policy.minimumReleaseAge | string | number | Retener releases más nuevos que esta antigüedad. Cadena de duración ("48h", "7d") o segundos. |
policy.minimumReleaseAgeExclude | string[] | DIDs (o pares <did>/<slug>) exentos de la retención. |
Consulta El registro de plugins para el flujo de trabajo completo, el modelo de confianza y cómo consultar el registro desde tu propio sitio.
Adaptadores de base de datos
Importa los adaptadores desde emdash/db:
import { sqlite, libsql, postgres } from "emdash/db";
sqlite(config)
Base de datos SQLite usando better-sqlite3.
| Opción | Tipo | Descripción |
|---|---|---|
url | string | Ruta de archivo con prefijo file: |
sqlite({ url: "file:./data.db" });
libsql(config)
Base de datos libSQL.
| Opción | Tipo | Descripción |
|---|---|---|
url | string | URL de la base de datos |
authToken | string | Token de auth (opcional para archivos locales) |
libsql({
url: process.env.LIBSQL_DATABASE_URL,
authToken: process.env.LIBSQL_AUTH_TOKEN,
});
postgres(config)
Base de datos PostgreSQL con connection pooling.
| Opción | Tipo | Descripción |
|---|---|---|
connectionString | string | URL de conexión PostgreSQL |
host | string | Host de la base de datos |
port | number | Puerto de la base de datos |
database | string | Nombre de la base de datos |
user | string | Usuario de la base de datos |
password | string | Contraseña de la base de datos |
ssl | boolean | Habilitar SSL |
pool.min | number | Tamaño mínimo del pool (defecto: 0) |
pool.max | number | Tamaño máximo del pool (defecto: 10) |
postgres({ connectionString: process.env.DATABASE_URL });
d1(config)
Base de datos Cloudflare D1. Importar desde @emdash-cms/cloudflare.
| Opción | Tipo | Por defecto | Descripción |
|---|---|---|---|
binding | string | — | Nombre del binding D1 de wrangler.jsonc |
session | string | "disabled" | Modo de replicación de lectura: "disabled", "auto" o "primary-first" |
bookmarkCookie | string | "__em_d1_bookmark" | Nombre de cookie para marcadores de sesión |
// Básico
d1({ binding: "DB" });
// Con réplicas de lectura
d1({ binding: "DB", session: "auto" });
Adaptadores de almacenamiento
Importa local y s3 desde emdash/astro. El adaptador r2 se importa desde @emdash-cms/cloudflare:
import emdash, { local, s3 } from "emdash/astro";
import { r2 } from "@emdash-cms/cloudflare";
local(config)
Almacenamiento en sistema de archivos local.
| Opción | Tipo | Descripción |
|---|---|---|
directory | string | Ruta del directorio |
baseUrl | string | URL base para servir archivos |
local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
});
r2(config)
Binding Cloudflare R2.
| Opción | Tipo | Descripción |
|---|---|---|
binding | string | Nombre del binding R2 |
publicUrl | string | URL pública opcional |
r2({
binding: "MEDIA",
publicUrl: "https://pub-xxxx.r2.dev",
});
s3(config?)
Almacenamiento compatible con S3. Todos los campos de configuración son opcionales: cualquier campo omitido de s3({...}) se resuelve desde la variable de entorno S3_* correspondiente cuando el proceso Node inicia. Los valores explícitos siempre tienen precedencia.
Prerrequisito: instala @aws-sdk/client-s3 y @aws-sdk/s3-request-presigner en tu proyecto. El core de EmDash no incluye el AWS SDK. Consulta Opciones de Almacenamiento: Almacenamiento Compatible con S3 para detalles.
| Opción | Tipo | Descripción |
|---|---|---|
endpoint | string | URL del endpoint S3 (S3_ENDPOINT) |
bucket | string | Nombre del bucket (S3_BUCKET) |
accessKeyId | string | Clave de acceso (S3_ACCESS_KEY_ID) |
secretAccessKey | string | Clave secreta (S3_SECRET_ACCESS_KEY) |
region | string | Región, defecto "auto" (S3_REGION) |
publicUrl | string | URL CDN opcional (S3_PUBLIC_URL) |
// Todos los campos desde variables de entorno S3_*
s3()
// Mix: CDN desde configuración, resto desde entorno
s3({ publicUrl: "https://cdn.example.com" })
// Todos explícitos
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",
})
Adaptadores de object cache
Pasa uno de estos a la opción objectCache.
kvCache(config)
Backend Cloudflare KV, compartido entre todos los isolates. Importar desde @emdash-cms/cloudflare.
kvCache({
binding: "CACHE",
defaultTtl: 3600,
revalidate: 1000,
timeout: 2000,
keyPrefix: "em",
})
memoryCache(config?)
Backend en proceso para Node.js y desarrollo. Importar desde emdash/astro.
memoryCache({
defaultTtl: 3600,
revalidate: 1000,
maxEntries: 1000,
keyPrefix: "em",
})
Consulta Object Cache para configuración y comportamiento.
Colecciones en vivo
Configura el loader de EmDash en src/live.config.ts:
import { defineLiveCollection } from "astro:content";
import { emdashLoader } from "emdash/runtime";
export const collections = {
_emdash: defineLiveCollection({
loader: emdashLoader(),
}),
};
Opciones del loader
La función emdashLoader() no toma argumentos:
emdashLoader();
Variables de entorno
EmDash respeta estas variables de entorno:
| Variable | Descripción |
|---|---|
EMDASH_SITE_URL | Origen público orientado al navegador (recurre a SITE_URL) |
EMDASH_ALLOWED_ORIGINS | Lista separada por comas de orígenes adicionales aceptados por la verificación de passkey (despliegues multi-subdominio). |
EMDASH_DATABASE_URL | Sobrescribir URL de la base de datos |
EMDASH_ENCRYPTION_KEY | Clave para cifrar secretos de plugins en reposo. Proporcionada por el operador — nunca almacenada en la base de datos. |
EMDASH_PREVIEW_SECRET | Sobrescritura opcional para el secreto HMAC de vista previa. Cuando no está establecido, se genera y almacena un valor estable por sitio en la base de datos. |
EMDASH_IP_SALT | Sobrescritura opcional para el salt del hash IP del comentarista. Cuando no está establecido, se genera y almacena un valor estable por sitio en la base de datos. |
EMDASH_AUTH_SECRET | Legacy. Usado como fuente de salt IP si está establecido; las instalaciones existentes deberían mantenerlo para preservar hashes IP de comentaristas estables durante la actualización. |
EMDASH_TURNSTILE_SECRET_KEY | Clave secreta de Cloudflare Turnstile (recurre a TURNSTILE_SECRET_KEY). Cuando está establecida, las presentaciones de comentarios deben incluir un token Turnstile válido — combínala con la prop turnstileSiteKey en <CommentForm>. |
EMDASH_URL | URL remota de EmDash para sincronización de schema |
Genera una clave de cifrado con el siguiente comando:
npx emdash secrets generate
Configuración de package.json
Las plantillas y sitios pueden declarar metadatos opcionales bajo una clave emdash en package.json:
{
"emdash": {
"label": "My Blog Template",
"seed": ".emdash/seed.json",
"url": "https://my-site.pages.dev"
}
}
| Opción | Descripción |
|---|---|
label | Nombre de la plantilla para mostrar |
seed | Ruta al archivo seed JSON |
url | URL remota para sincronización de schema |
Configuración TypeScript
EmDash genera tipos en .emdash/types.ts. Agrega un alias de ruta a tu tsconfig.json:
{
"compilerOptions": {
"paths": {
"@emdash-cms/types": ["./.emdash/types.ts"]
}
}
}
Genera tipos con el siguiente comando:
npx emdash types