Aller au contenu

Référence de Configuration

EmDash est configuré via deux fichiers : astro.config.mjs pour l’intégration et src/live.config.ts pour les collections de contenu.

Configurez EmDash en tant qu’intégration Astro :

astro.config.mjs
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: [],
}),
],
});

Obligatoire. Configuration de l’adaptateur de base de données.

// 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 (importer depuis @emdash-cms/cloudflare)
database: d1({ binding: "DB" });

Voir Options de base de données pour plus de détails.

Obligatoire. Configuration de l’adaptateur de stockage multimédia.

// Local filesystem (development)
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
});
// Liaison R2 (Cloudflare Workers)
storage: r2({
binding: "MEDIA",
publicUrl: "https://pub-xxxx.r2.dev", // optional
});
// Compatible S3 (toute plateforme)
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
});

Voir Options de stockage pour plus de détails.

Optionnel. Tableau de plugins EmDash.

import seoPlugin from "@emdash-cms/plugin-seo";
plugins: [seoPlugin()];

Optionnel. Configuration de l’authentification.

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

Permet aux utilisateurs de s’inscrire eux-mêmes si leur domaine email est autorisé.

OptionTypePar défautDescription
domainsstring[][]Domaines email autorisés
defaultRolenumber20Rôle pour les auto-inscriptions
selfSignup: {
domains: ["example.com", "acme.org"],
defaultRole: 20, // Contributor
}

Configure les fournisseurs de connexion 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,
},
}

Configuration de la session.

OptionTypePar défautDescription
maxAgenumber2592000 (30j)Durée de vie de la session en secondes
slidingbooleantrueRéinitialise l’expiration à l’activité

Utilise Cloudflare Access comme fournisseur d’authentification à la place des passkeys.

OptionTypePar défautDescription
teamDomainstringrequisVotre domaine d’équipe Access
audiencestringrequisÉtiquette Audience de l’application (AUD)
autoProvisionbooleantrueCrée les utilisateurs à la première connexion
defaultRolenumber30Rôle par défaut pour les nouveaux utilisateurs
syncRolesbooleanfalseMet à jour le rôle à chaque connexion
roleMappingobject—Mappe les groupes IdP vers les rôles

Optionnel. Fournissez une origine complète côté navigateur (schéma + hôte + port optionnel, pas de chemin) pour que le rpId et l’origin de WebAuthn correspondent à ce que le navigateur de l’utilisateur envoie dans clientData.origin.

Par défaut, les passkeys suivent Astro.url / request.url. Derrière un proxy inverse terminant TLS, l’application voit souvent encore http:// sur le saut interne alors que l’onglet est https://, ou l’hôte reconstruit ne correspond pas au nom public — ce qui casse la vérification des passkeys. Définissez passkeyPublicOrigin sur l’origine que les utilisateurs tapent dans la barre d’adresse (par exemple https://cms.example.com ou https://cms.example.com:8443).

L’intégration valide cette valeur au chargement : elle doit être une URL valide avec le protocole http: ou https: et est normalisée en origin.

emdash({
database: sqlite({ url: "file:./data.db" }),
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
}),
passkeyPublicOrigin: "https://cms.example.com",
});

Astro ne reflète les en-têtes X-Forwarded-* que lorsque l’hôte public est autorisé. Configurez security.allowedDomains pour le nom d’hôte (et les schémas) que vos utilisateurs atteignent. Dans astro dev, ajoutez les vite.server.allowedHosts correspondants pour que Vite accepte l’en-tête Host du proxy.

Préférez d’abord corriger allowedDomains (et les en-têtes transmis) ; utilisez passkeyPublicOrigin lorsque l’URL reconstruite diverge toujours de l’origine du navigateur (typique lorsque TLS est terminé en amont et que la requête en amont reste http://).

Avec TLS en amont, lier le serveur de développement à loopback (astro dev --host 127.0.0.1) est souvent suffisant : le proxy se connecte localement tandis que passkeyPublicOrigin correspond à l’origine HTTPS publique.

js title="astro.config.mjs (excerpt)"
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",
}),
],
});

Importez depuis emdash/db :

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

Base de données SQLite utilisant better-sqlite3.

OptionTypeDescription
urlstringChemin du fichier avec préfixe file:
sqlite({ url: "file:./data.db" });

Base de données libSQL.

OptionTypeDescription
urlstringURL de la base de données
authTokenstringJeton d’authentification (optionnel pour les fichiers locaux)
libsql({
url: process.env.LIBSQL_DATABASE_URL,
authToken: process.env.LIBSQL_AUTH_TOKEN,
});

Base de données PostgreSQL avec pool de connexions.

OptionTypeDescription
connectionStringstringURL de connexion PostgreSQL
hoststringHôte de la base de données
portnumberPort de la base de données
databasestringNom de la base de données
userstringUtilisateur de la base de données
passwordstringMot de passe de la base de données
sslbooleanActiver SSL
pool.minnumberTaille minimale du pool (par défaut : 0)
pool.maxnumberTaille maximale du pool (par défaut : 10)
postgres({ connectionString: process.env.DATABASE_URL });

Base de données Cloudflare D1. Importez depuis @emdash-cms/cloudflare.

OptionTypeDefaultDescription
bindingstring—Nom de la liaison D1 depuis wrangler.jsonc
sessionstring"disabled"Mode de réplication en lecture : "disabled", "auto", ou "primary-first"
bookmarkCookiestring"__ec_d1_bookmark"Nom du cookie pour les marque-pages de session
// Basic
d1({ binding: "DB" });
// Avec des réplicas de lecture
d1({ binding: "DB", session: "auto" });

Lorsque session est défini sur "auto" ou "primary-first", EmDash utilise l’API D1 Sessions pour acheminer les requêtes de lecture vers les réplicas les plus proches. Les utilisateurs authentifiés bénéficient d’une cohérence lecture-écriture basée sur des marque-pages. Voir Options de base de données — Réplicas de lecture pour plus de détails.

Importer depuis emdash/astro :

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

Stockage sur le système de fichiers local.

OptionTypeDescription
directorystringChemin du répertoire
baseUrlstringURL de base pour servir les fichiers
local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
});

Liaison Cloudflare R2.

OptionTypeDescription
bindingstringNom de la liaison R2
publicUrlstringURL publique optionnelle
r2({
binding: "MEDIA",
publicUrl: "https://pub-xxxx.r2.dev",
});

Stockage compatible S3.

OptionTypeDescription
endpointstringURL du point de terminaison S3
bucketstringNom du compartiment
accessKeyIdstringClé d’accès
secretAccessKeystringClé secrète
regionstringRégion (par défaut : "auto")
publicUrlstringURL CDN optionnelle
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",
});

Configurez le chargeur EmDash dans src/live.config.ts :

ts title="src/live.config.ts"
import { defineLiveCollection } from "astro:content";
import { emdashLoader } from "emdash/runtime";
export const collections = {
_emdash: defineLiveCollection({
loader: emdashLoader(),
}),
};

La fonction emdashLoader() accepte une configuration optionnelle :

emdashLoader({
// Currently no options - reserved for future use
});

EmDash respecte ces variables d’environnement :

VariableDescription
EMDASH_DATABASE_URLRemplace l’URL de la base de données
EMDASH_AUTH_SECRETSecret pour l’authentification par clé d’accès
EMDASH_PREVIEW_SECRETSecret pour la génération de jetons de prévisualisation
EMDASH_URLURL EmDash distante pour la synchronisation du schéma

Générez un secret d’authentification avec :

Fenêtre de terminal
npx emdash auth secret

Configuration optionnelle dans package.json :

json title="package.json"
{
"emdash": {
"label": "Mon modèle de blog",
"description": "Un modèle de blog épuré et minimaliste",
"seed": ".emdash/seed.json",
"url": "https://my-site.pages.dev",
"preview": "https://emdash-blog.pages.dev"
}
}
OptionDescription
labelNom du modèle pour l’affichage
descriptionDescription du modèle
seedChemin vers le fichier JSON d’amorçage
urlURL distante pour la synchronisation du schéma
previewURL du site de démonstration pour la prévisualisation du modèle

EmDash génère les types dans .emdash/types.ts. Ajoutez à votre tsconfig.json :

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

Générez les types avec :

Fenêtre de terminal
npx emdash types