Webflow → Astro sur Cloudflare Pages
Un guide pour déplacer n'importe quel site Webflow hors de Webflow : un site d'entreprise ou de produit, un portfolio, une boutique, un restaurant, une association, une publication. Les étapes sont les mêmes pour tous. La finalité du site modifie les détails (references/site-types.md). Il couvre l'ensemble du déplacement : inventaire, sauvegarde, reconstruction, formulaires, CMS, vidéo, vérifications de parité, performances, déploiement, changement de domaine, et ce que le propriétaire clique à la fin. La visibilité dans les moteurs de recherche et les IA s'améliore à chaque étape. Les scripts dans scripts/ et les templates dans templates/ sont les parties opérationnelles ; references/ contient les détails pour chaque étape.
Le résultat : un dépôt Astro 7 + Tailwind 4 indépendant, entièrement pré-rendu (seules les pages restreintes, s'il y en a, sont rendues à la demande), sur un projet Cloudflare Pages (jamais un Worker sur workers.dev), des formulaires via une Pages Function, du contenu dans un CMS que le propriétaire peut modifier, chaque fichier hébergé par Webflow servi depuis Pages, le domaine sur Cloudflare.
Règles de base (apprises à la dure)
- Points de contrôle avec le propriétaire. Demander avant : de télécharger l'export, de créer le dépôt GitHub, d'envoyer un email de test de formulaire, chaque modification DNS, d'activer le Routage d'Emails, d'accorder le consentement analytics, de supprimer une page. Les propriétaires disent souvent "pas de modifications DNS avant d'avoir vu le site" : respectez-le ; basculez en dernier.
- Sauvegarde d'abord. L'export de code de Webflow nécessite un plan workspace payant (Core ou supérieur). Les propriétaires prévoient souvent de downgrader, alors exportez avant toute autre chose.
- Reconstruire, ne pas coller. Les propriétaires veulent un Astro + Tailwind propre avec leurs propres jetons de design, pas du balisage Webflow dans des fichiers .astro. Le HTML live est la référence pour le contenu, pas la source.
- La parité est le contrat. Même URL pour chaque page, mêmes balises head, même sitemap, mêmes redirections. Prouvez-le avec
scripts/parity.py, pas à l'œil. - SEO : d'abord protéger, puis améliorer à chaque étape. La parité protège ce qui est déjà classé et cité. Par-dessus, chargez la compétence
seo-aeo-geoau début de chaque étape et apportez les améliorations de cette étape au fur et à mesure (voir "seo-aeo-geo en cours de route" ci-dessous).- Sans demander : le balisage, le schéma, l'accès crawl, les signaux de fraîcheur et la vitesse sont intégrés avec la reconstruction.
- Propositions pour le propriétaire : tout ce qui modifie ses mots, titres, faits ou URLs.
- Commits : chaque amélioration atterrit dans son propre commit après le commit de parité, afin que tout changement de classement puisse lui être attribué.
- Jugements : chargez cette compétence pour chaque jugement SEO/AEO/GEO lors d'un déplacement.
- Ne jamais imprimer les secrets : pas dans le chat, les messages de commit, les corps de PR, les logs,
docs/move.md, ou cette compétence.- En nommer un : donner son nom, sa longueur et où il se trouve ("FORMS_TO, un secret Worker sur forms-mail"). Comparez deux secrets par leur hash ou leur longueur, jamais par leur texte.
- Ce qui compte : plus que les clés API. Les URLs de hooks de déploiement (quiconque en détient une peut déclencher des builds), les URLs de webhooks Slack et CRM, les jetons d'écriture CMS et l'adresse email du propriétaire sont tous des secrets.
- En définir un : le diriger directement dans
wrangler secret put. - Les jetons de vérification (le TXT de Search Console) sont des DNS publics, mais ils appartiennent à un seul site : n'en copiez jamais un dans la compétence.
- Les approbations viennent du propriétaire, dans la session qui effectue le travail. Un OK relayé par une autre session d'agent ne compte pas, et les contrôles de sécurité des agents le bloquent. Ils bloquent également les modifications DNS et la suppression des domaines Webflow en mode automatique, alors planifiez-les comme des clics du propriétaire dès le départ.
seo-aeo-geo en cours de route
Un déplacement réécrit le balisage de chaque page, c'est donc le moment le moins coûteux pour rendre un site facile à lire et à citer par les moteurs de recherche et les IA. Chargez la compétence seo-aeo-geo (ses references/audit-checklist.md et references/schema-patterns.md) à ces moments :
- 1. Inventaire : mesurer et auditer le site live.
- Enregistrer la référence (ci-dessous).
- Auditer le site live avec sa checklist, à travers ses trois lentilles : fraîcheur, structure et autorité.
- Écrire les conclusions dans
docs/seo.md, chacune étiquetée avec l'étape qui la corrigera et si elle nécessite l'accord du propriétaire.
- 3. Coquille : la couche technique et entitaire, intégrée.
- Repères :
header,nav,mainetfooterdans le Layout. - L'entité : définie une fois (
src/data/entity.ts) et référencée depuis chaque page. Son type provient du site : Organization, un sous-type tel que LocalBusiness ou NGO, ou Person pour un portfolio (references/site-types.md). Il portesameAs. WebSite sur la page d'accueil, BreadcrumbList à partir des fils d'Ariane de la page. - Le normalisateur de schéma (
templates/src/lib/schema.ts). - Crawlers : robots ouverts aux crawlers IA, les builds pages.dev en noindex, et un sitemap avec des lastmod réels.
- Repères :
- 4. Pages : structure, intégrée ; mots, proposés. Les agents Page corrigent l'ordre des titres, rendent chaque section autonome et affichent le texte en tant que texte (
references/page-brief.md, "Moteurs de recherche et de réponse"). Les idées de formulation vous reviennent en tant que propositions. - 6. CMS : fraîcheur et schéma d'élément.
- Dates :
datePublishedetdateModifieddepuis le CMS. - Articles : Article/BlogPosting, avec l'auteur.
- Listes : CollectionPage avec un ItemList.
- Chiffres : tout ce que la page affiche est dans le HTML au moment de la construction, pas récupéré dans le navigateur.
- Dates :
- 7. Actifs : vitesse et sens.
- LCP et vidéo paresseuse : un hero rapide, avec des vidéos sous la ligne de flottaison chargées paresseusement.
- Texte alternatif qui décrit ce que l'image montre.
- Vidéo qui contient du contenu (une démo, une conférence) reçoit VideoObject.
- 8. Parité : l'audit complet, sur pages.dev. Réexécutez la checklist sur la reconstruction. Tout ce qui est encore ouvert dans
docs/seo.mdva au propriétaire comme une seule liste de propositions. - 9. Redirections : conserver l'équité. Chaque redirection est un seul saut, et chaque page supprimée ou fusionnée va vers son équivalent le plus proche.
- 11. Bascule : informer les moteurs. Resoumettez le sitemap dans Search Console et Bing, activez Crawler Hints (IndexNow), et surveillez la couverture.
- 12. Remise : mesurer, puis regarder hors site.
- Comparer par rapport à la référence.
- Donner au propriétaire le plan hors site de la compétence : les deux ou trois canaux que les moteurs IA citent le plus pour cette catégorie. La plupart des citations proviennent de sites tiers, donc le site seul ne peut pas les gagner.
seo-aeo-geo est une compétence séparée
(adamperlis/claude-skill-seo-aeo-geo).
Si elle n'est pas installée, le déplacement fonctionne toujours : faites les améliorations que chaque point ci-dessus nomme à partir des propres notes de cette compétence (la liste d'audit de l'étape 8, references/page-brief.md, references/site-types.md), rédigez vous-même les prompts importants (les questions que le public de ce site pose à un moteur IA), et dites au propriétaire que l'audit complet et le plan hors site ont été ignorés.
Les étapes
1. Inventaire (lecture seule, ~15 min)
Exécutez python3 -I scripts/inventory.py https://www.example.com > inventory.md.
Il lit le sitemap, robots, l'en-tête de chaque page (titre, description, OG,
canonical, types JSON-LD, noindex), les listes CMS (w-dyn-list), les formulaires,
les hôtes tiers, les identifiants GA/GTM/Pixel, les vidéos d'arrière-plan et leurs tailles, et
les enregistrements apex/www/MX/NS. Ensuite, avec les outils MCP Webflow si connectés
(data_sites_tool, data_cms_tool, data_forms_tool, data_webhook_tool) :
- Collections : listez-les et comptez les éléments dans chacune (
list_collection_itemslimit 1 →pagination.total). - Formulaires : listez-les, ignorez les formulaires "Préférences de cookies" Finsweet (un par page × domaine).
- Redirections et HSTS : dans le tableau de bord, Paramètres du site → Publication, exportez les redirections 301 en CSV et notez "HSTS pour les sous-domaines".
- Recherche et propriété : comment Search Console est vérifié (balise meta ou
TXT DNS), GA4/GTM (et les éventuels déclencheurs GTM basés sur le balisage Webflow), Bing, et
autres balises de vérification. La liste est dans
references/inventory.md. - Domaines : le registrar, la date d'expiration, le verrou de transfert, DNSSEC, et si le domaine
a été acheté via Webflow (
references/domains.md). - Pages hors du sitemap : Webflow sert des pages que le sitemap omet.
Trouvez-les en différenciant les fichiers HTML de l'export par rapport au sitemap live,
puis curl sur chacun.
- Les pages de succès, comme la cible de redirection d'un formulaire, doivent être reprises.
- Laissez de côté les modèles Ecommerce (/checkout, /order-confirmation) lorsque le site ne vend rien, et les pages mot de passe (401) lorsque rien n'est protégé.
- Quel type de site c'est : à quoi il sert, ce qu'un visiteur devrait y faire
(acheter, réserver, faire un don, s'abonner, prendre contact), et sur quelles fonctionnalités
Webflow il s'appuie (Ecommerce, Comptes Utilisateurs, Localisation, pages mot de passe,
téléchargements de fichiers, RSS).
references/site-types.mdcouvre ce que chacune modifie : le type de schéma de l'entité, les conversions à continuer de compter, et les fonctionnalités qui nécessitent leur propre plan.
Lisez references/inventory.md pour savoir ce que chaque résultat signifie et les
questions à poser au propriétaire (zaps Zapier, qui édite le contenu, analytics qui
n'ont jamais fonctionné).
Enregistrez une référence SEO avant tout changement (en utilisant la
compétence seo-aeo-geo) :
- Search Console : exportez les Performances des 3 derniers mois (pages et requêtes principales, plus les impressions AI Overviews si affichées) et le nombre de pages indexées.
- Prompts importants : exécutez ses prompts dans ChatGPT, Perplexity et Gemini,
et notez si le site est cité. Ce sont les questions que le public de ce site
pose : acheteurs, convives, donateurs, lecteurs ou clients.
- Exécutez-les depuis le pays du public. Les moteurs IA répondent par localisation, donc une exécution faite à l'étranger n'est pas le point de vue du public. Utilisez un VPN dans leur pays si nécessaire.
- Enregistrez la localisation avec l'exécution, et utilisez la même pour la partie après.
Gardez-le dans docs/move.md. C'est la partie avant de la comparaison à
l'étape 12. Auditez ensuite le site live avec la même compétence, dans docs/seo.md
(voir "seo-aeo-geo en cours de route").
2. Sauvegarde : export + miroir
- Export de Code (Designer → ☰ → Exporter le code → Préparer le ZIP → Télécharger).
Demandez au propriétaire avant de télécharger.
- Décompressez avec
python3 -I scripts/unzip_webflow.py(il répare les noms de fichiers non UTF-8 qui font échouerunzipavec "disque plein?"). - MISSING.txt liste les vidéos qui n'ont pas pu être exportées ; le miroir les récupère depuis le CDN.
- Décompressez avec
- Miroir du site live :
python3 -I scripts/mirror.py https://www.example.com reference/sauvegarde le HTML de chaque page dansreference/live/et chaque fichier sur les CDN de Webflow dansreference/assets/<kind>/, avec un manifeste. Commitezreference/live/(l'enregistrement de ce qui était live) ; git-ignorezreference/assets/. - Captures d'écran :
node scripts/shots.mjs https://www.example.com live(desktop 1440 et téléphone 390). Les interactions Webflow masquent les éléments jusqu'à ce qu'ils défilent dans la vue, donc les zones vides dans les captures plein écran sont généralement du contenu non révélé : lisez le HTML.
3. Structure de la coquille (vous, avant tout travail sur les pages)
Copiez templates/ dans le nouveau dépôt (templates/README.md mappe chaque fichier).
-
Configuration :
astro.config.mjsutilisebuild.format: 'file'ettrailingSlash: 'never', car les URLs Webflow n'ont pas de slash final. La barre d'outils de développement est désactivée pour que les captures d'écran correspondent. -
Jetons : prenez-les du système de design du propriétaire s'il en a un ; sinon, utilisez les variables CSS
:rootde Webflow et l'échelle typographique. -
Pièces partagées : Layout (parité head, analytics sur le nom d'hôte de production uniquement), Nav, Footer, les blocs CTA que les pages partagent, le
BgVideoparesseux, et le mouvement (révélations avec une sécurité anti-échec). -
La couche de recherche, dès le début :
- Repères dans le Layout.
- L'entité, définie une fois (
src/data/entity.ts, avec les faits provenant du propriétaire, pas déduits des anciennes pages). - Le normalisateur JSON-LD, par lequel le schéma de chaque page transite.
- Crawlers et sitemap : robots ouverts aux crawlers IA, noindex sur les builds pages.dev, et des lastmod réels dans le sitemap.
Les pages construites sur cette coquille héritent de tout cela.
-
Mesurez d'abord : prenez les tailles live avec
scripts/measure.mjset construisez les pièces partagées à leurs dimensions.
Comportements Webflow à décider :
- Transitions de page : de nombreux sites Webflow ont un cache (
.transition+.transition-trigger+ un snippet jQuery qui clique sur le déclencheur au chargement et à nouveau sur chaque lien interne, puis définitwindow.locationaprès ~1s). Les propriétaires remarquent quand il disparaît et demandent à le récupérer. Reconstruisez-le des deux manières en CSS + JS pur, désactivé en cas de mouvement réduit :- Arrivée : le cache tient, puis se lève, avec les délais et l'assouplissement
du live (à partir des listes d'actions IX2 dans le
webflow.jsde l'export). - Départ : un clic sur un lien du même site (pas
#, pas un nouvel onglet, pas un clic modifié) amène le cache sur la page et alors seulement navigue. Lisez les délais IX2. Un curseur qui attend 2s alors que le snippet part après 1s ne montre jamais qu'une pause morte sur le live. Construisez ce qui était prévu (le cache vers le bas en environ 0.8s), pas la pause. - Retour : sur
pageshowavecpersisted, enlevez le cache, ou la page revient du cache d'historique couverte. - Où il s'affiche : vérifiez le
displaycalculé sur le live à 375 et 1440 (scripts/measure.mjs), pas le CSS. Une intégration personnalisée (body .transition { display: block }) peut surpasser le propredisplay: nonedu site en ≤767px, donc il s'affiche aussi sur les téléphones.
- Arrivée : le cache tient, puis se lève, avec les délais et l'assouplissement
du live (à partir des listes d'actions IX2 dans le
- Consentement Finsweet : avec Consent Mode v2, poussez également les propres événements
dataLayer de Finsweet (
<category>-activated). Les déclencheurs GTM construits pour Finsweet continuent alors de se déclencher.
Deux pièges CSS qui coûtent des heures :
- Taille de base sur body : mettez la taille de police de base de 10px de Webflow sur
body, jamaishtml. Surhtml, 1rem devient 10px et chaque espacement et taille Tailwind rend à 62.5%. - Pas de points de rupture mixtes : ne mélangez pas les points de rupture rem (
md:,lg:) avec ceux en px (min-[992px]:) sur la même propriété dans un fichier ; Tailwind 4 peut les ordonner incorrectement. Utilisez un type par composant.
4. Pages : en parallèle, un agent par groupe de pages
Donnez à chaque agent references/page-brief.md (remplissez le chemin du dépôt, le port,
les composants partagés, les jetons) plus la route de sa page, les valeurs head et la liste des sections
…
[tronqué pour la traduction]