stitch::extract-static-html

Par google-labs-code · stitch-skills

Extrayez du HTML statique autonome depuis une application web buildée ou des composants React en inlinant le CSS et les images. Utilisez cette skill chaque fois que vous avez besoin de capturer un état d'interface spécifique, de partager une version statique d'une page, ou de préparer des assets pour un upload Stitch, même si l'utilisateur demande simplement de « sauvegarder le HTML » ou de « mocker la vue ».

npx skills add https://github.com/google-labs-code/stitch-skills --skill stitch::extract-static-html

Extraire du HTML statique

Extraire un fichier HTML statique autonome à partir de n'importe quelle application web.

Quelle stratégie utiliser

Vous DEVEZ demander à l'utilisateur de choisir quelle stratégie utiliser avant de continuer. Présentez les options clairement, recommandez la stratégie A comme valeur par défaut préférée, et fournissez un résumé bref avantages/inconvénients pour chaque option pour l'aider à prendre une décision éclairée.

Stratégie A (Puppeteer) Stratégie B (Subagent navigateur)
Quand App exécutée localement, pas de mur d'authentification Besoin d'interagir avec la page d'abord (cliquer, remplir des formulaires)
Fidélité Maximale — styles calculés résolus Élevée — DOM rendu
Configuration Zéro — aucun mock nécessaire Zéro — aucun mock nécessaire
Framework Quelconque Quelconque
Sortie Écrit dans un fichier — pas de limite de taille Peut être tronquée dans le contexte agent

[!WARNING] Point de contrôle — Confirmation utilisateur requise. Vous DEVEZ demander à l'utilisateur quelle stratégie il préfère avant de continuer. Présentez le tableau de comparaison ci-dessus, recommandez la stratégie A par défaut, et attendez l'approbation explicite. Ne DÉCIDEZ PAS vous-même et ne continuez PAS jusqu'à la confirmation de l'utilisateur.


Stratégie A : Snapshot Puppeteer (Recommandé)

Lance Chrome sans interface, capture le DOM entièrement rendu, et produit un fichier HTML autonome avec tout le CSS intégré et les images en base64. Fonctionne avec n'importe quel framework — aucun MockPage.jsx nécessaire.

Prérequis

  • App exécutée localement (par exemple, npm run dev)
  • Node.js avec puppeteer disponible (vérifiez : node -e "require('puppeteer')")

Flux de travail

  1. Démarrer l'app et noter le port.

    [!WARNING] Point de contrôle — Confirmation utilisateur requise. Après avoir démarré le serveur local, vous DEVEZ faire une pause et demander la confirmation de l'utilisateur avant d'exécuter le script snapshot ou de lancer un subagent navigateur. Rapportez l'URL et le port à l'utilisateur afin qu'il puisse vérifier que l'app s'exécute et s'affiche correctement. Ne CONTINUEZ PAS jusqu'à l'étape snapshot jusqu'à la confirmation de l'utilisateur.

  2. Exécutez le script snapshot :

    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173 \
      --output .stitch/home.html \
      --wait 2000
  3. Pages multiples — exécutez une fois par route :

    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173 --output .stitch/home.html --wait 2000
    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173/pricing --output .stitch/pricing.html --wait 2000
    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173/dashboard --output .stitch/dashboard.html --wait 2000 --html-class dark

Drapeaux du script

Drapeau Par défaut Description
--url (requis) URL à capturer
--output (requis) Chemin du fichier de sortie
--wait 1000 Attente supplémentaire (ms) après l'inactivité réseau. Augmentez pour les apps avec chargement différé.
--viewport 1280x800 Taille de la fenêtre comme LARGEURxHAUTEUR
--html-class Classe(s) pour l'élément <html> (par exemple, dark)
--remove-fixed false Supprimer les éléments fixed/sticky (bandeaux de cookies, widgets de chat)
--full-height false Redimensionner la fenêtre à la hauteur complète du défilement
--title Remplacer le titre de la page

Ce qu'il fait automatiquement

  • Intègre tous les <link rel="stylesheet"> → blocs <style>
  • Convertit les src des <img> et srcset → data URIs base64 (ignore les polices)
  • Intègre les URLs <source srcset> en base64
  • Supprime les entrées srcset défaillantes/mortes pour que le navigateur revienne au src intégré
  • Supprime les balises <script>, l'overlay Vite, les indicateurs de développement Next.js
  • Résout les chemins url() CSS relatifs avant intégration

Remarques par framework

Framework Remarques
React + Vite Fonctionne d'emblée. --wait 1000.
Next.js --wait 3000 pour l'hydratation SSR. URL : http://localhost:3000. <img srcset> depuis /_next/image est intégré automatiquement en base64.
Vue / Nuxt Fonctionne d'emblée.
Svelte / SvelteKit Fonctionne d'emblée.
Storybook Utilisez l'URL de story : --url http://localhost:6006/?path=/story/...
SSR (Webpack) Peut nécessiter un --wait plus long.

Dépannage

Problème Solution
Images manquantes Augmentez --wait
Les images s'affichent cassées après arrêt du serveur Vérifiez que srcset a été intégré — consultez le journal pour « Inlined N images ». Si les URLs srcset ont échoué, elles sont auto-supprimées pour que src (intégré) soit utilisé.
Next.js /_next/image non intégré Assurez-vous que le serveur de développement s'exécute lors de l'execution du snapshot — le script récupère les images optimisées depuis le serveur en cours d'exécution.
Mode sombre non appliqué --html-class dark
Bandeau de cookies dans la sortie --remove-fixed
La page nécessite une connexion Utilisez le Static Fallback (appendice ci-dessous)
Cannot find module 'puppeteer' npm install -g puppeteer

Stratégie B : Capture avec subagent navigateur

À utiliser quand vous devez interagir avec la page (cliquer sur des boutons, remplir des formulaires, naviguer dans les onglets) avant de la capturer. Le subagent navigateur vous donne un contrôle total mais la sortie peut être tronquée pour les grandes pages.

Flux de travail

  1. Démarrer l'app localement.

  2. Naviguer en utilisant un subagent navigateur.

  3. Interagir comme nécessaire (cliquer, défiler, remplir des formulaires).

  4. Extraire le DOM : document.documentElement.outerHTML

    [!WARNING] Les grandes pages peuvent être tronquées. Pour gérer cela :

    • Supprimez les balises <style> avant extraction : document.querySelectorAll('style').forEach(el => el.remove())
    • Rajoutez les styles statiquement (lien CDN Tailwind, CSS source)
  5. Enregistrer dans un fichier.


Appendice : Fallback statique (MockPage.jsx)

[!NOTE] Cette méthode est un dernier recours pour quand l'app ne peut pas s'exécuter localement (dépendances cassées, backend manquant, murs d'authentification sans contournement). Elle nécessite d'aplatir manuellement les composants React en un seul fichier JSX. Préférez la stratégie A chaque fois que possible.

Quand l'utiliser

  • L'app ne peut pas du tout s'exécuter localement
  • La page nécessite une authentification sans mock/contournement
  • Vous avez besoin d'un état UI spécifique impossible à atteindre par navigation (écrans d'erreur, états vides)

Référence rapide

npx tsx <SKILL_DIR>/scripts/extract_inline_html.ts \
  --index-css src/css/App.css \
  --extra-css index.html \
  --outdir .stitch \
  --page src/MockPage.jsx:Page.html:"Page Title"

Drapeaux clés : --no-tailwind (apps non-Tailwind), --html-class dark (mode sombre), --css-files (fichiers CSS supplémentaires).

Auto-détection : La configuration Tailwind est auto-détectée. Les directives @apply utilisent automatiquement <style type="text/tailwindcss">.

Règles MockPage.jsx

  1. Inclure la mise en page complète — en-tête, barre latérale, pied de page (lisez d'abord App.js)
  2. Aplatir tous les conditionnels — choisissez un état, supprimez tous les ternaires et gardes &&
  3. Coder en dur toutes les données — remplacez {variable} par des valeurs concrètes, déroulez les boucles .map()
  4. Conserver les logos — utilisez <img> avec des chemins locaux (le post-traitement les intégrera)
  5. Supprimer les éléments flottants — bandeaux de cookies, widgets de chat, boutons de rétroaction

Post-traitement

Intégrer les images locales :

npx tsx <SKILL_DIR>/scripts/post_process.ts \
  .stitch/Page.html --base-dir <app-directory>

Skills similaires