Ce guide déploie un site EmDash sur Cloudflare Workers avec D1 pour sa base de données et R2 pour les médias. Partez d’un template EmDash Cloudflare ou appliquez la même configuration à un site Astro existant.
Prérequis
- Un compte Cloudflare
- Les dépendances du projet installées
- Wrangler authentifié auprès de Cloudflare (
pnpm wrangler login)
Configurer les bindings
Les templates Cloudflare incluent le point d’entrée Worker complet ainsi que des bindings D1 et R2 nommés. Lors du premier déploiement, Wrangler crée l’une ou l’autre de ces ressources si le nom configuré n’existe pas encore. Conservez les noms dans wrangler.jsonc ; Wrangler reconnecte les déploiements suivants aux mêmes ressources.
Le template utilise les bindings suivants :
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "my-emdash-site",
"main": "./src/worker.ts",
"compatibility_date": "2026-02-24",
"compatibility_flags": ["nodejs_compat"],
"d1_databases": [
{
"binding": "DB",
"database_name": "my-emdash-site",
},
],
"r2_buckets": [
{
"binding": "MEDIA",
"bucket_name": "my-emdash-media",
},
],
"worker_loaders": [{ "binding": "LOADER" }],
"triggers": { "crons": ["* * * * *"] },
}
Les noms DB, MEDIA et LOADER doivent correspondre aux adaptateurs EmDash. Le Cron Trigger exécute la publication planifiée, les tâches de plugins, les sauvegardes et la maintenance. Consultez Plugin sandbox si le site utilise des plugins en sandbox.
Configurer EmDash
La configuration Astro suivante utilise les bindings D1 et R2.
import { defineConfig } from "astro/config";
import cloudflare from "@astrojs/cloudflare";
import react from "@astrojs/react";
import emdash from "emdash/astro";
import { d1, r2, sandbox } from "@emdash-cms/cloudflare";
export default defineConfig({
output: "server",
adapter: cloudflare(),
integrations: [
react(), // Required — the admin UI is a React app
emdash({
database: d1({ binding: "DB" }),
storage: r2({ binding: "MEDIA" }),
sandboxRunner: sandbox(),
}),
],
});
Si le site n’utilise ni plugins marketplace, ni registry, ni plugins sandboxed, omettez sandboxRunner et le binding LOADER.
Ajouter le point d’entrée Worker
Le point d’entrée Worker connecte Astro au Cron Trigger et exporte le pont de plugins :
import handler, { createScheduledHandler, PluginBridge } from "@emdash-cms/cloudflare/worker";
export { PluginBridge };
export default {
...handler,
scheduled: createScheduledHandler(),
} satisfies ExportedHandler;
L’export PluginBridge est sans conséquence lorsqu’aucun plugin en sandbox n’est installé. Conservez-le si le même projet peut activer des plugins plus tard.
Pour exécuter la maintenance générale selon un autre calendrier que chaque minute, passez la même expression Cron à createScheduledHandler({ generalCron: "..." }) et à triggers.crons. Si elles diffèrent, le handler journalise le déclenchement inattendu et l’ignore.
Construire et déployer
Construisez et déployez le site une fois pour que Wrangler provisionne la base de données D1 et le bucket R2 nommés. Wrangler utilise la connexion locale créée par pnpm wrangler login.
pnpm build
pnpm wrangler deploy
Avec le mode de migration auto par défaut, EmDash applique les migrations du cœur en attente lorsque le Worker déployé reçoit sa première requête. Le Worker laisse les migrations de contenu volumineuses à emdash migrate et répond par un 503 tant qu’elles ne sont pas appliquées. Utilisez Manage core database migrations lorsqu’un pipeline de déploiement doit appliquer les migrations avant que le nouveau code ne reçoive du trafic, ou lorsque vous devez inspecter, vérifier ou récupérer une migration.
Tant que l’assistant de configuration n’est pas terminé, EmDash applique aussi une seule fois, à la première requête, le schéma et la structure d’un fichier seed. Le contenu d’exemple du seed n’est appliqué que lorsqu’un administrateur le choisit dans l’assistant de configuration. Le seed est lu au moment du build depuis .emdash/seed.json, le chemin indiqué dans package.json#emdash.seed ou seed/seed.json — le premier trouvé — puis intégré au bundle. Si aucun n’est présent, un seed par défaut intégré est utilisé. Les déploiements suivants sur une base de données existante ne touchent pas à son contenu.
Pour modifier le schéma ou le modèle de contenu d’un site déjà déployé, consultez Evolving a Deployed Site.
Publication planifiée
Sur Cloudflare, EmDash ne publie les entrées planifiées que depuis le handler scheduled du Worker, que Cloudflare appelle selon le calendrier d’un Cron Trigger. Le Worker déployé a besoin des deux éléments suivants :
- Un Cron Trigger dans la liste
triggers.cronsdewrangler.jsonc, comme indiqué dans Configurer les bindings. - Le handler
scheduledde@emdash-cms/cloudflare/worker, exporté depuis le point d’entrée Worker vers lequel pointemain, comme indiqué dans Ajouter le point d’entrée Worker.
Si l’un des deux manque, les entrées planifiées ne sont pas mises en ligne. En développement local avec astro dev, EmDash publie les entrées planifiées à l’aide d’un minuteur ; un calendrier qui fonctionne en local ne confirme donc pas la configuration déployée.
Exécutez emdash doctor depuis la racine du projet pour vérifier le Cron Trigger et le handler scheduled dans les fichiers du projet local :
pnpm emdash doctor
Lorsque emdash doctor trouve les deux, la sortie inclut une vérification scheduler wiring réussie. Une vérification du planificateur en échec décrit le problème et affiche la correction. La vérification reconnaît le point d’entrée Worker présenté sur cette page et le ré-export d’une ligne qu’elle affiche comme correction ; un point d’entrée écrit autrement peut donc échouer à la vérification même s’il fonctionne.
Si aucune vérification du planificateur n’apparaît, emdash doctor n’a trouvé aucune configuration Wrangler dans le répertoire courant, ou n’a trouvé ni le Cron Trigger ni le handler scheduled. Sur un projet D1, la vérification database échoue car elle recherche un fichier SQLite local (./data.db par défaut). Cet échec n’affecte pas les vérifications du planificateur.
Redéployez après avoir ajouté ou modifié le Cron Trigger ou le handler scheduled. Cloudflare peut mettre jusqu’à 15 minutes pour commencer à exécuter un Cron Trigger nouveau ou modifié. Une fois que le déclencheur s’exécute, EmDash publie les entrées dont l’heure planifiée est déjà passée.
Pour observer le déclencheur, exécutez pnpm wrangler tail. Chaque exécution affiche une ligne telle que "* * * * *" @ 9/29/2026, 10:01:00 AM - Ok. Ok signifie que l’exécution s’est terminée sans erreur non interceptée. EmDash intercepte et journalise les erreurs de publication ; Ok ne confirme donc pas que des entrées ont été publiées. Une exécution qui publie des entrées journalise aussi un message tel que [scheduled] Published 1 scheduled item(s), et les erreurs de l’exécution apparaissent dans la même sortie.
Après le déploiement, le tableau de bord d’administration affiche Scheduled publishing needs attention lorsqu’une entrée planifiée a dépassé son heure planifiée et qu’aucune exécution du planificateur ne s’est terminée au cours des cinq dernières minutes. Si le Cron Trigger s’exécute moins souvent que toutes les cinq minutes, l’avis peut aussi apparaître entre deux exécutions, jusqu’à ce que la suivante publie l’entrée.
Placer le Worker près de D1
Cloudflare exécute par défaut un Worker près du visiteur. Les requêtes rendues côté serveur d’EmDash font plusieurs allers-retours vers D1 ; utilisez donc Targeted Placement pour exécuter le Worker près du primaire D1 et accélérer ces requêtes.
Wrangler accepte placement.mode: "targeted" avec exactement un sélecteur : region, host ou hostname. Sélectionnez la valeur qui cible l’emplacement du primaire D1, puis ajoutez l’objet placement obtenu à wrangler.jsonc. N’activez pas les réplicas en lecture D1 avec Targeted Placement. Sans réplicas, chaque requête utilise le primaire proche, y compris avec session: "auto" et coalesce: true.
Cache d’objets
Pour réduire la charge de lecture sur D1, mettez en cache dans Cloudflare KV les résultats des requêtes de contenu et de configuration. Les lectures sont servies depuis KV au lieu d’interroger la base de données à chaque requête :
import { d1, r2, kvCache } from "@emdash-cms/cloudflare";
emdash({
database: d1({ binding: "DB" }),
storage: r2({ binding: "MEDIA" }),
objectCache: kvCache({ binding: "CACHE" }),
}),
Consultez Object Cache pour la configuration de KV, les options et le comportement d’invalidation.
Workers Cache
Workers Cache de Cloudflare place un cache en périphérie devant votre Worker : les requêtes correspondantes sont servies sans exécuter votre Worker du tout.
L’activer
Utilisez le fournisseur de cache Cloudflare d’Astro afin que les règles de route et Astro.cache définissent les en-têtes de cache et que le fournisseur puisse invalider les entrées lorsque le contenu change.
import { cacheCloudflare } from "@astrojs/cloudflare/cache";
export default defineConfig({
adapter: cloudflare(),
cache: {
provider: cacheCloudflare(),
},
routeRules: {
"/": { maxAge: 300, swr: 86400, tags: ["posts", "pages"] },
// D’autres routes publiques peuvent utiliser des durées de cache différentes.
},
});
L’adaptateur @astrojs/cloudflare détecte cacheCloudflare() et active Workers Cache dans la configuration de déploiement générée.
EmDash invalide automatiquement les entrées en cache lorsque le contenu change (voir Cache de routes pour la convention de balises). Vous n’avez à purger vous-même que pour des balises personnalisées, par exemple un interrupteur manuel « tout effacer », en utilisant l’API de purge de la plateforme depuis votre Worker. Elle ne nécessite aucun identifiant de l’API REST de Cloudflare.
Les pages publiques contrôlent leur propre mise en cache via routeRules et Astro.cache. Limitez les règles de route à vos routes publiques : un paramètre rest à la racine du site, comme /[...slug], correspond aussi aux routes d’administration et d’API sous /_emdash/.
Deux points à connaître avant de l’activer :
- Une réponse portant un hint de cache est mettable en cache, même sans règle de route. L’adaptateur marque comme
no-storeles réponses qu’aucune règle de route ni aucun appel àAstro.cache.set()n’a rendues mettables en cache. Un hint avec des balises mais sansmaxAge, comme les hints de paramètres du site et de menu qu’un layout définit sur chaque page, produitCloudflare-CDN-Cache-Control: publicsans durée de vie : Workers Cache se rabat alors sur ses durées de cache par défaut (2 heures pour une réponse200). Donnez à chaque route publique une règle, et gardez les routes dépendantes de la session exemptes de hints de cache. - Les pages en cache sont partagées avec les éditeurs connectés. Le cache s’exécute avant votre Worker ; il ne peut donc pas être contourné en fonction des cookies de la requête. Avec la barre d’outils rendue côté serveur par défaut, un éditeur connecté peut recevoir la variante anonyme en cache d’une page publique, sans la barre d’outils d’édition visuelle, jusqu’à l’expiration de l’entrée. Définissez
toolbar: "client"pour que la barre d’outils reste fiable sur les pages en cache. Les pages rendues pour un utilisateur connecté ne sont jamais stockées dans le cache de routes.
Pour un guide plus complet couvrant les règles de route, les balises de cache, l’invalidation intégrée d’EmDash à la publication et les réponses qui doivent rester hors du cache, voir Cache de routes.
Workers Caching est distinct du cache d’objets (objectCache: kvCache({ binding: "CACHE" })), qui met en cache les résultats des requêtes de base de données dans KV sous le Worker.
Domaines personnalisés
Le premier déploiement reçoit une URL workers.dev. Le domaine personnalisé doit déjà être un domaine actif géré par Cloudflare dans le même compte que le Worker. Une fois que le Worker répond correctement à son URL workers.dev, ajoutez le domaine de production comme route Wrangler :
{
"routes": [{ "pattern": "www.example.com", "custom_domain": true }],
}
Redéployez et vérifiez les deux adresses. Garder l’adresse workers.dev disponible pendant les tests DNS aide à distinguer un problème de routage d’un problème d’application. Pour que le nouveau domaine devienne l’adresse utilisée dans les sitemaps et les métadonnées de recherche, ainsi que dans les e-mails et les plugins lorsque siteUrl, EMDASH_SITE_URL ou SITE_URL n’est pas défini, utilisez Change domain dans Settings > General ; voir Passer à un nouveau domaine.
Sans siteUrl, EMDASH_SITE_URL ni SITE_URL, la configuration enregistre l’adresse sur laquelle elle s’exécute comme origine du site, et les passkeys créées pendant la configuration ne fonctionnent que sur cette adresse. Exécutez la configuration sur le domaine de production, ou définissez EMDASH_SITE_URL sur ce domaine avant la configuration. Si vous définissez EMDASH_SITE_URL sur un autre domaine après la configuration, la connexion passe à ce domaine, et les passkeys créées sur l’ancienne adresse cessent d’y fonctionner.
Accès R2 public
Par défaut, les médias sont servis via la route média authentifiée d’EmDash. Si le bucket possède un domaine personnalisé public, définissez cette origine comme publicUrl afin que les URL de médias générées l’utilisent :
storage: r2({
binding: "MEDIA",
publicUrl: "https://media.example.com",
}),
L’accès public au bucket s’applique à chaque objet accessible, pas seulement aux médias. Les sauvegardes JSON automatiques utilisent le préfixe backups/ dans le même backend de stockage ; n’exposez donc pas ce préfixe via le domaine public. Choose media storage explique la limite à respecter.
Transformation d’images
EmDash redimensionne et réencode les médias R2 dans le Worker, via le binding IMAGES de Cloudflare. Le composant Image de emdash/ui et les images dans le texte enrichi sont tous deux rendus via l’endpoint d’images qu’EmDash installe sous l’adaptateur Cloudflare. Pour les médias sur la route interne /_emdash/api/media/file/…, cet endpoint lit les octets sources directement depuis le binding R2, sans récupération HTTP. Ces transformations continuent de fonctionner derrière Cloudflare Access et avec global_fetch_strictly_public. Les médias servis depuis une URL de bucket — voir Accès R2 public — utilisent à la place l’endpoint de transformation propre à l’adaptateur, qui récupère le fichier via HTTP avant de le transformer.
Vous n’avez pas besoin de déclarer le binding. @astrojs/cloudflare l’ajoute à la configuration du Worker qu’il génère pendant astro build, de la même façon qu’il ajoute cache pour Workers Caching. Il le fait chaque fois que le service d’images à l’exécution est cloudflare-binding : imageService non défini, la chaîne elle-même, ou { runtime: "cloudflare-binding" }. Toute autre valeur — "passthrough", "compile", "cloudflare", "custom" — omet le binding. Le lister dans votre propre wrangler.jsonc rend l’intention évidente :
{
"images": {
"binding": "IMAGES",
},
}
Pour voir ce qu’un déploiement obtient réellement, lisez la configuration générée plutôt que wrangler.jsonc. Un build écrit .wrangler/deploy/config.json, qui oriente wrangler deploy vers le fichier fusionné (dist/server/wrangler.json par défaut). Cherchez-y une entrée images.
Cloudflare facture ces transformations comme des Images transformations. Chaque combinaison unique d’image source et de paramètres est facturée une fois par mois calendaire, et les requêtes répétées au cours de ce mois sont gratuites. Si un site a 500 images sources et demande une taille de miniature et une taille de héros pour chaque image, ces deux jeux de paramètres comptent pour 1 000 images transformées ce mois-là. Le plan Images Free couvre 5 000 transformations uniques par mois. Au-delà de cette limite, les transformations en cache sont toujours servies, mais les nouvelles renvoient une erreur 9422 et la requête d’image échoue.
Authentification Cloudflare Access
Cloudflare Access peut remplacer l’authentification par passkey par le fournisseur d’identité rattaché à une application Access. La valeur d’audience est un paramètre d’exécution secret ; gardez-la hors de astro.config.mjs en nommant sa variable d’environnement :
import { access } from "@emdash-cms/cloudflare";
emdash({
auth: access({
teamDomain: "myteam.cloudflareaccess.com",
audienceEnvVar: "CF_ACCESS_AUDIENCE",
roleMapping: {
Admins: 50,
Editors: 40,
},
}),
}),
Définissez CF_ACCESS_AUDIENCE avec pnpm wrangler secret put CF_ACCESS_AUDIENCE. Le authentication guide explique le provisionnement des utilisateurs, les rôles par défaut et la synchronisation des rôles.
Les Workers de production n’ont pas de service d’envoi d’e-mails par défaut. La connexion par lien magique renvoie Email is not configured tant qu’un plugin d’e-mail n’est pas actif.
Le plugin d’e-mail Cloudflare utilise un binding send_email. Enregistrez et vérifiez d’abord le domaine expéditeur avec Cloudflare Email Sending. Cloudflare rejette les messages dont l’adresse From n’est pas un expéditeur accepté.
Ajoutez le binding et enregistrez le fournisseur :
{
"send_email": [{ "name": "EMAIL" }],
}
import { cloudflareEmail } from "@emdash-cms/cloudflare/plugins";
emdash({
plugins: [
cloudflareEmail({
from: { email: "[email protected]", name: "My Site CMS" },
replyTo: "[email protected]",
}),
],
}),
Le plugin est actif dès son premier déploiement. Settings → Email affiche le fournisseur sélectionné et permet d’envoyer un e-mail de test. L’envoi échoue tant que l’expéditeur n’est pas accepté et que le binding n’existe pas.
Le plugin utilise le binding nommé EMAIL, sauf si son option binding en désigne un autre. S’il est le seul fournisseur d’e-mail actif, EmDash le sélectionne automatiquement. Si plusieurs fournisseurs sont actifs, choisissez le fournisseur Cloudflare sous Settings → Email. L’adresse facultative replyTo reçoit les réponses sans modifier l’adresse From acceptée. Un plugin peut définir replyTo sur un message individuel, ce qui remplace cette option pour ce message.
Cloudflare AI Search
Pour ajouter Cloudflare AI Search au site, installez le plugin AI Search.
Secrets Worker
Stockez les valeurs secrètes avec pnpm wrangler secret put <NAME>. Ne les placez pas dans wrangler.jsonc et ne les lisez pas à partir des valeurs import.meta.env au moment du build.
EMDASH_ENCRYPTION_KEY chiffre les paramètres de plugin déclarés comme secrets. Définissez-la avant d’enregistrer un secret de plugin et conservez-la séparément des sauvegardes D1. Pendant la rotation, fournissez d’abord la nouvelle clé et conservez les anciennes clés après des virgules jusqu’à ce que chaque secret de plugin ait été de nouveau enregistré. Secrets and key management décrit la rotation et la récupération.
Le pont de plugins lit directement ce binding de secret Worker. La route de paramètres d’administration générée le lit via process.env. Avec nodejs_compat, Cloudflare renseigne process.env par défaut pour les dates de compatibilité à partir de 2025-04-01. Les projets fixés à une date antérieure doivent aussi ajouter nodejs_compat_populate_process_env avant d’enregistrer des paramètres chiffrés.
EmDash lit ses secrets depuis process.env à l’exécution. Le code du Worker lit les bindings depuis env, importé de cloudflare:workers. Ne lisez jamais les secrets via import.meta.env : Vite remplace ces valeurs au moment du build et peut les écrire dans le bundle serveur.
Le secret HMAC de prévisualisation et le sel d’IP des commentateurs sont générés et stockés dans la base de données, sauf si vous fournissez des remplacements à l’exécution. Secrets and key management liste les variables exactes, les emplacements de stockage et les effets de la rotation.
Déploiements de prévisualisation
Une prévisualisation peut s’exécuter comme Worker Preview, qui attribue à chaque branche sa propre URL sur le Worker de production, ou comme Worker distinct dans un environnement Wrangler nommé. Dans les deux cas, la prévisualisation a besoin d’une base de données et d’un bucket distincts de ceux de la production. Ne pointez jamais un binding de prévisualisation vers une base de données ou un bucket de production.
Worker Previews
Worker Previews exige Wrangler 4.135.0 ou plus récent dans les dépendances du projet. Les projets créés à partir d’un ancien template EmDash peuvent épingler une version antérieure ; mettez-la à niveau avec pnpm add -D wrangler@latest. Les prévisualisations n’héritent ni des bindings ni de vars de la configuration de premier niveau ; listez dans un bloc previews chaque binding utilisé par la prévisualisation.
L’adaptateur Astro pour Cloudflare ajoute un binding KV SESSION. wrangler deploy le provisionne automatiquement, mais wrangler preview le rejette sans ID d’espace de noms. Créez les ressources de prévisualisation, y compris un espace de noms KV pour les sessions :
pnpm wrangler d1 create my-emdash-site-preview
pnpm wrangler r2 bucket create my-emdash-media-preview
pnpm wrangler kv namespace create my-emdash-site-preview-session
Ajoutez à wrangler.jsonc les identifiants de ressources affichés par Wrangler :
{
"previews": {
"d1_databases": [
{
"binding": "DB",
"database_name": "my-emdash-site-preview",
"database_id": "00000000-0000-0000-0000-000000000000",
},
],
"r2_buckets": [
{
"binding": "MEDIA",
"bucket_name": "my-emdash-media-preview",
},
],
"kv_namespaces": [{ "binding": "SESSION", "id": "00000000000000000000000000000000" }],
"worker_loaders": [{ "binding": "LOADER" }],
},
}
Répétez send_email, AI Search, vars et les autres bindings lorsque la prévisualisation utilise ces fonctionnalités.
L’assistant de configuration et les passkeys ont besoin de l’URL du site de la prévisualisation. Sans siteUrl ni EMDASH_SITE_URL, la configuration échoue avec SITE_URL_REQUIRED. Transmettez l’URL de prévisualisation, https://<preview-name>-<worker-name>.<subdomain>.workers.dev, à chaque déploiement de prévisualisation :
pnpm build
pnpm wrangler preview --name my-branch \
--var EMDASH_SITE_URL:https://my-branch-my-emdash-site.example.workers.dev
Utilisez le même nom de prévisualisation dans --name et dans l’URL. Un siteUrl dans astro.config.mjs l’emporte sur EMDASH_SITE_URL et est intégré à chaque prévisualisation ; les passkeys de la prévisualisation sont alors liées au domaine de production, et ni la configuration ni la connexion n’y fonctionnent. Définissez plutôt l’URL de production avec EMDASH_SITE_URL dans les vars de premier niveau.
Si le Worker définit workers_dev sur false, les prévisualisations n’ont pas d’URL tant que vous n’avez pas défini "preview_urls": true au premier niveau de wrangler.jsonc et exécuté wrangler deploy une fois. wrangler preview n’applique pas ce paramètre. wrangler deploy publie en production le code de votre checkout actuel, et pas seulement le paramètre : validez donc la modification par un commit et déployez depuis un checkout propre de votre branche de production. Revenez ensuite à votre branche et exécutez de nouveau wrangler preview.
Définissez un secret pour une seule prévisualisation avec pnpm wrangler preview secret put <NAME> --name my-branch. pnpm wrangler preview base-config secret put <NAME> définit un secret pour les prévisualisations créées ensuite ; les prévisualisations existantes conservent leurs secrets.
Gardez à l’esprit ces différences avec la production :
- Les prévisualisations partagent les ressources du bloc
previews.wrangler previewlit le blocpreviewsde la branche qu’il déploie ; toute branche qui conserve la configuration de la branche de base utilise donc la même base de données. La première requête vers une prévisualisation applique les migrations du noyau en attente : une branche qui met EmDash à niveau migre donc aussi la base de données utilisée par les autres prévisualisations. Pour isoler une branche, créez une autre base de données D1 et modifiezdatabase_nameetdatabase_iddans le blocpreviewsde cette branche avant de la déployer. - Une base de données de prévisualisation vide affiche l’assistant de configuration. Les URL de prévisualisation sont publiques, et le premier visiteur à terminer l’assistant devient l’administrateur. Terminez la configuration immédiatement après avoir créé la prévisualisation, ou protégez les URL de prévisualisation avec Cloudflare Access.
- Les Cron Triggers ne s’exécutent pas. Les publications programmées ne sont pas publiées, et les tâches cron des plugins et les sauvegardes programmées ne s’exécutent pas sur une prévisualisation.
- Les passkeys ne fonctionnent que sur le nom d’hôte qui les a enregistrées. Les passkeys de production ne fonctionnent pas sur une prévisualisation, et l’administrateur créé sur la première prévisualisation ne peut se connecter avec une passkey que sur cette URL de prévisualisation. Sur une autre prévisualisation qui partage la base de données, connectez-vous avec un lien magique, qui nécessite un fournisseur d’e-mail et son binding dans le bloc
previews, puis ajoutez-y une passkey. Vous pouvez aussi isoler la branche avec sa propre base de données comme décrit ci-dessus et y exécuter la configuration.
Environnements nommés
Les environnements Wrangler nommés n’héritent pas des bindings. Créez des ressources de prévisualisation distinctes et écrivez-les dans l’environnement preview avant le build :
pnpm wrangler d1 create my-emdash-site-preview \
--binding DB --env preview --update-config
pnpm wrangler r2 bucket create my-emdash-media-preview \
--binding MEDIA --env preview --update-config
L’environnement de prévisualisation doit répéter chaque binding utilisé par le Worker de prévisualisation. Les bindings D1, R2 et sandbox du cœur ont cette forme après que Wrangler a écrit les identifiants de ressources :
{
"env": {
"preview": {
"d1_databases": [
{
"binding": "DB",
"database_name": "my-emdash-site-preview",
"database_id": "00000000-0000-0000-0000-000000000000",
},
],
"r2_buckets": [
{
"binding": "MEDIA",
"bucket_name": "my-emdash-media-preview",
},
],
"worker_loaders": [{ "binding": "LOADER" }],
},
},
}
Utilisez l’UUID de prévisualisation écrit par Wrangler. Répétez les bindings facultatifs KV, AI Search, e-mail et autres lorsque la prévisualisation utilise ces fonctionnalités. Ajoutez les secrets propres à la prévisualisation avec pnpm wrangler secret put <NAME> --env preview.
Construisez et déployez l’environnement de prévisualisation. Sa première requête applique les migrations du cœur en attente via le mode auto par défaut.
pnpm build
pnpm wrangler deploy --env preview
Vérifiez l’URL de prévisualisation, la connexion à l’administration, l’envoi de médias et tout binding facultatif avant de la partager.
Vérifier le déploiement
Après le déploiement, demandez une page publique, connectez-vous à /_emdash/admin, envoyez et récupérez un fichier média de test, et confirmez que le handler scheduled apparaît dans pnpm wrangler tail.
Dépannage
« D1 binding not found »
Vérifiez que le nom du binding dans wrangler.jsonc correspond à la configuration de votre base de données :
// Must match: d1({ binding: "DB" })
"binding": "DB"
« R2 binding not found »
Vérifiez que le bucket R2 est correctement lié :
// Must match: r2({ binding: "MEDIA" })
"binding": "MEDIA"
Erreurs de migration
Si vous voyez des erreurs de schéma, suivez les journaux du Worker (wrangler tail) et reproduisez l’erreur pour capturer le message sous-jacent — puis ouvrez une issue avec cette sortie.