# Créer une extension Chrome avec l’IA (Manifest V3)

URL: https://agentvera.dev/fr/blog/build-chrome-extension-with-ai/ · Publié: 2026-10-11

Créez une extension Chrome avec l’IA : Manifest V3, content scripts, service worker, permissions minimales, clés d’API protégées et publication sur le Chrome Web Store.

**En bref:**

- Une extension Manifest V3 a quatre éléments : manifest.json, un content script, un service worker et un popup ou une page d’options ; le service worker s’arrête à l’inactivité, gardez donc l’état dans chrome.storage.
- Demandez des permissions minimales comme activeTab, scripting et storage, évitez <all_urls> et n’embarquez jamais de clé d’API dans l’extension ; appelez le modèle via un serveur proxy.
- Testez avec Load unpacked dans chrome://extensions ; le Chrome Web Store demande des frais uniques et une justification pour chaque permission, et une nouvelle permission peut désactiver l’extension jusqu’à validation.

Créer une extension Chrome avec l’IA est l’une des portes d’entrée les plus simples au vibe coding : une extension, ce sont quelques petits fichiers, vous la testez dans votre propre navigateur sans aucun serveur, et les agents de code comme Claude Code ou Codex connaissent bien la structure du Manifest V3. Le plus dur n’est pas le code ; c’est de choisir le bon élément (content script, service worker, popup), de demander le moins de permissions possible et de ne jamais mettre de clés d’API dans l’extension. Cet article décrit le chemin que je suis, d’un dossier vide au Chrome Web Store.

Comme exemple, nous allons construire quelque chose de petit mais réel : une extension qui résume l’article de la page courante avec une API d’IA. Avec le [vibe coding](/fr/glossary/vibe-coding/), vous pouvez avoir une première version en un après-midi ; la version que vous publiez demande quelques règles de plus.

## Connaître d’abord les éléments

Pour dire à l’agent ce que vous voulez, il suffit de connaître les quatre blocs d’une extension Chrome :

- **`manifest.json` :** l’identité de l’extension. Nom, version, quel fichier fait quoi et quelles permissions elle demande. Les nouvelles extensions utilisent le Manifest V3.
- **Content script :** du JavaScript qui s’exécute dans la page visitée. Il peut lire le texte de la page, ajouter un bouton, masquer un élément. Il ne peut pas accéder directement aux variables JavaScript de la page ; il s’exécute dans un « monde » isolé.
- **Service worker (arrière-plan) :** du code qui s’exécute indépendamment de toute page. Il réagit à des événements comme un clic sur l’icône de la barre d’outils, un changement d’onglet ou des alarmes, et il fait des requêtes réseau. Une propriété importante : Chrome l’arrête quand il est inactif, donc tout ce qui est gardé dans une variable globale peut disparaître.
- **Popup et page d’options :** la petite fenêtre qui s’ouvre quand vous cliquez sur l’icône, et une page séparée pour les réglages. Ce sont deux pages HTML ordinaires.

Ces éléments communiquent avec `chrome.runtime.sendMessage` et `chrome.tabs.sendMessage`. Quand quelque chose écrit par l’agent « ne marche pas », la cause est très souvent du code exécuté au mauvais endroit, par exemple en essayant d’utiliser `document` dans le service worker.

## 1. Installation et structure du projet

Ce qu’il vous faut : Chrome (ou un autre navigateur Chromium), Git, un éditeur de code et un [agent de code](/fr/glossary/coding-agent/). Un outil de build n’est pas nécessaire pour une première extension ; du JavaScript pur suffit. Si le projet grandit, les frameworks d’extension basés sur Vite comme WXT ajoutent TypeScript et le rechargement automatique, mais je laisserais cette couche de côté pour la version un. Les erreurs de l’agent sont plus faciles à voir sans elle.

```bash
mkdir page-summarizer && cd page-summarizer
git init
```

Mettez ensuite à la racine du projet un court fichier de règles que l’agent lit à chaque session (`CLAUDE.md` ou `AGENTS.md`) :

```markdown
# Page Summarizer (Chrome extension)
- Manifest V3, plain JavaScript, no build step.
- Minimal permissions: activeTab, scripting, storage. No <all_urls>.
- No remote code; no eval, no remote <script>.
- No API key in the extension; requests go to our own server.
- Persistent state in chrome.storage, not in service worker globals.
- Ask before adding a permission or a package.
```

## 2. Le premier prompt

Dans le premier message, je demande à l’agent d’expliquer ce qu’il va construire et quels fichiers il va créer, puis d’écrire le code :

```text
Read CLAUDE.md. Build a Manifest V3 Chrome extension:
- Clicking the toolbar icon opens a popup with a "Summarize" button.
- Pressing it grabs the article text from the active tab (use activeTab +
  scripting and inject the content script only at that moment).
- The text goes to the service worker, which POSTs it to
  https://api.my-server.example/summarize.
- Show the summary in the popup; on error show a readable message.
- Keep the last 10 summaries in chrome.storage.local.
First list the files and what each one does, then create them.
Finish with step-by-step instructions to load and test it.
```

Le `manifest.json` produit par l’agent devrait ressembler à peu près à ceci :

```json
{
  "manifest_version": 3,
  "name": "Page Summarizer",
  "version": "0.1.0",
  "description": "Summarizes the article on the current page in one click.",
  "action": { "default_popup": "popup.html" },
  "background": { "service_worker": "background.js" },
  "permissions": ["activeTab", "scripting", "storage"],
  "host_permissions": ["https://api.my-server.example/*"]
}
```

Ce que je vérifie ici, c’est la liste des permissions. `activeTab` donne un accès temporaire au seul onglet courant quand l’utilisateur clique sur l’icône. Les agents ajoutent souvent `"<all_urls>"` ou `"tabs"` par commodité ; cela affiche aux utilisateurs un avertissement effrayant et ralentit la revue du store.

## 3. Charger, tester, déboguer

Avant de vous approcher du store, testez l’extension dans votre propre navigateur :

1. Ouvrez `chrome://extensions`.
2. Activez le **mode développeur** en haut à droite.
3. Cliquez sur **Load unpacked** (Charger l’extension non empaquetée) et choisissez le dossier du projet.
4. Épinglez l’icône dans la barre d’outils et essayez-la sur un article.

Après avoir modifié le code, appuyez sur le bouton de rechargement de la carte de l’extension dans `chrome://extensions`. Si un content script a changé, rechargez aussi la page sur laquelle vous testez.

Les trois endroits les plus utiles pour déboguer :

- **Service worker :** le lien « service worker » sur la carte de l’extension ouvre ses propres DevTools. Les requêtes réseau et les erreurs d’arrière-plan s’y affichent.
- **Popup :** avec le popup ouvert, faites un clic droit dessus et choisissez **Inspecter**.
- **Content script :** les logs apparaissent dans la console DevTools de la page elle-même ; vous pouvez choisir votre extension dans la liste de contexte en haut de la console.

Si la carte de l’extension affiche un bouton **Errors**, copiez son contenu tel quel et donnez-le à l’agent :

```text
I loaded the extension. Pressing "Summarize" in the popup shows this error:
[error text]
The service worker console also shows:
[log]
Explain the cause, fix it, and list what you changed in which file.
```

Dire où ça casse, sur quoi vous avez cliqué et ce que montre chaque console permet à l’agent de corriger le problème au lieu de deviner.

## 4. Stockage : choisir le bon endroit

- **`chrome.storage.local` :** des données sur cet appareil, comme l’historique des résumés.
- **`chrome.storage.sync` :** synchronisé entre appareils via le profil Chrome de l’utilisateur. Le quota est petit ; réservez-le aux réglages.
- **`chrome.storage.session` :** effacé à la fermeture du navigateur ; pratique pour un état temporaire qui doit survivre au redémarrage du service worker.

Il n’y a pas de `localStorage` dans un service worker. Si l’agent essaie de l’utiliser, c’est pour cela que ça échoue. Et n’oubliez pas la permission `storage` dans `manifest.json`.

## 5. Gardez les clés d’API hors de l’extension

C’est l’erreur que je vois le plus dans les extensions créées par IA. L’agent écrit « collez votre clé OpenAI ici » et met une constante dans `background.js`. Une extension publiée est un fichier ZIP ; n’importe qui peut le télécharger, le décompresser et lire votre clé. Minifier ou obfusquer n’y change rien.

La bonne structure est un petit proxy :

1. L’extension appelle votre propre serveur (`https://api.my-server.example/summarize`).
2. Le serveur garde la clé dans son environnement et appelle la vraie API d’IA.
3. Le serveur limite le débit des requêtes (par utilisateur ou IP) et rejette les textes trop gros.

Ouvrez un projet séparé pour ce serveur et dites à l’agent :

```text
Write a small HTTP service: POST /summarize takes { text } in the body.
Cap the text at 20,000 characters, call the AI API with the key from an
environment variable, return { summary }. Allow CORS only for the
chrome-extension://<EXTENSION_ID> origin. Add a simple rate limit.
Never log the key. Create a .env.example file.
```

L’identifiant de l’extension s’affiche dans `chrome://extensions` quand vous la chargez non empaquetée ; une fois publiée dans le store, il peut être différent. Mettez à jour le réglage CORS avant de publier. Si les utilisateurs apportent leur propre clé (courant pour les outils de développeur), demandez-la dans la page d’options et gardez-la dans `chrome.storage.local` ; n’embarquez jamais la vôtre.

## Ce que l’IA se trompe à faire

- **Écrire du code Manifest V2.** `background.page`, `chrome.browserAction`, une page d’arrière-plan persistante ou `webRequestBlocking` viennent d’anciens exemples. Dites à l’agent « utilise l’équivalent Manifest V3 ».
- **Supposer que le service worker tourne toujours.** Un compteur dans une variable globale ou un `setInterval` s’arrête au bout d’un moment. Utilisez `chrome.alarms` pour le travail planifié et `chrome.storage` pour l’état.
- **Demander trop de permissions.** `<all_urls>`, `tabs`, `history` sont généralement inutiles. Demandez à l’agent de justifier chaque permission en une phrase ; supprimez celles qu’il ne sait pas justifier.
- **Charger du code distant.** Tirer une bibliothèque d’un CDN avec `<script>` ou utiliser `eval` n’est pas autorisé en Manifest V3. Intégrez la bibliothèque au paquet.
- **Chercher des variables de la page depuis un content script.** Comme il s’exécute dans un monde isolé, il ne voit pas `window.someApp` ; il doit passer par le DOM.
- **Oublier les réponses asynchrones dans la messagerie.** Si un écouteur `onMessage` répond de façon asynchrone, il doit faire `return true`, sinon le popup reçoit une réponse vide.
- **Supposer que tous les sites ont le même HTML.** Pour récupérer le texte d’un article, cherchez d’abord un élément `article` ou `main` et prévoyez un repli raisonnable. Testez sur trois sites différents.

## Sécurité

- **Les secrets vivent dans `.env`, sur le serveur.** Pas de `.env` dans le dossier de l’extension ; il finirait dans le ZIP.
- **Ne collez jamais de clés d’API dans le chat.** L’agent a besoin du nom de la variable, pas de la clé.
- **Lisez les commandes que l’agent exécute.** En particulier les installations de paquets et tout ce qui ressemble à `curl … | sh`.
- **Ne faites pas confiance aux données de la page.** N’affichez pas dans le popup avec `innerHTML` le texte lu par le content script ; utilisez `textContent`. Sinon une page malveillante peut injecter du code dans votre extension.
- **Vérifiez d’où vient un message.** Si vous n’avez pas besoin de messages de l’extérieur, n’ajoutez pas `externally_connectable` ; si vous en avez besoin, gardez les origines autorisées étroites.
- **Ne collectez que le nécessaire.** Si le texte de la page part vers votre serveur, dites-le clairement et ne l’y stockez pas.

## 6. Publier sur le Chrome Web Store

Dans les grandes lignes, la publication se déroule ainsi :

1. **Créez un compte développeur.** Inscrivez-vous dans le tableau de bord développeur du Chrome Web Store ; il y a des frais d’inscription uniques.
2. **Empaquetez.** Compressez le dossier du projet en ZIP avec le manifest à la racine. Laissez de côté `.git`, `node_modules`, les fichiers de test et `.env`.
3. **Remplissez la fiche.** Description, captures d’écran, icônes, catégorie.
4. **Remplissez la section confidentialité.** Indiquez l’objectif unique de l’extension, justifiez chaque permission et déclarez les données utilisateur que vous collectez. Si vous collectez des données, il vous faut l’URL d’une politique de confidentialité publiquement accessible.
5. **Soumettez pour revue.** Le délai varie. De larges permissions d’hôte et du code difficile à lire peuvent le rallonger ; en cas de rejet, l’e-mail indique quelle règle vous avez enfreinte.

L’agent aide aussi ici :

```text
I'm submitting this extension to the Chrome Web Store. For each
permission in manifest.json, write a one-sentence justification for the
store form, write the single-purpose description and list the user data
we collect. Tell me if any permission looks unnecessary. Give me a command
that builds the release ZIP without .git, .env and test files.
```

Pour les mises à jour, incrémentez `version` dans `manifest.json`. Ajouter une nouvelle permission peut désactiver l’extension chez les utilisateurs existants tant qu’ils ne l’ont pas acceptée : réfléchissez-y à deux fois avant d’en ajouter une.

## Comment je procède avec AgentVera

Vous pouvez créer une extension avec un terminal et un navigateur. J’utilise AgentVera quand je construis l’extension et le serveur proxy en même temps :

- **Deux agents, deux tâches.** Dans l’[espace de travail](/fr/features/workspace/), j’ouvre un agent Claude Code pour l’extension et un agent Codex pour le serveur proxy, chacun dans son propre dossier ou [worktree git](/fr/glossary/git-worktree/).
- **Essayer le serveur.** Le [client API](/fr/features/api-client/) peut trouver les points d’accès du serveur à partir de son code ; j’y essaie `/summarize` avant de le brancher à l’extension.
- **Envoyer les erreurs à l’agent.** J’envoie la sortie d’erreur d’un terminal à l’agent choisi avec [Send to agent](/fr/features/send-to-agent/) au lieu de copier-coller.
- **Relire avant de fusionner.** La [revue de code](/fr/features/code-review/) contrôle chaque tour terminé, et le [panneau Git](/fr/features/git-and-github/) montre le diff. Une permission en trop ou une clé embarquée s’y fait généralement repérer.
- **Suivi des [tokens](/fr/glossary/token/).** Chaque volet affiche la taille du contexte en direct ; une petite extension n’a pas besoin d’une session gonflée.

Charger l’extension dans Chrome et l’essayer reste à votre charge ; AgentVera ne le fait pas pour vous.

## Pour conclure

Pour créer une extension Chrome avec l’IA, apprenez les éléments (manifest, content script, service worker, popup), donnez à l’agent des règles écrites, commencez avec des permissions minimales, chargez-la non empaquetée et déboguez depuis la bonne console, et gardez les clés d’API derrière un serveur proxy. Avant de soumettre au store, assurez-vous de pouvoir justifier chaque permission. Pour en savoir plus sur le contrôle de ce que produisent les agents, lisez [la revue de code par IA](/fr/blog/ai-code-review/), et pour choisir vos outils, [les meilleurs outils CLI de code IA](/fr/blog/best-ai-coding-cli-tools/).

## Questions fréquentes

**Puis-je créer une extension Chrome avec l’IA sans savoir coder ?** Une extension simple, oui ; la plupart des extensions tiennent en quelques petits fichiers qu’un agent de code sait écrire. Apprendre les bases, comme le manifest, les permissions et la façon dont les éléments s’échangent des messages, vous aide quand même à décrire précisément les bugs à l’agent.

**Quelle est la différence entre un content script et un service worker ?** Un content script s’exécute dans la page visitée et peut lire et modifier son DOM. Le service worker tourne en arrière-plan, indépendamment de toute page ; il réagit à des événements, fait des requêtes réseau et est arrêté par Chrome quand il est inactif.

**Comment cacher une clé d’API dans une extension Chrome ?** Vous ne le pouvez pas : tout ce que vous embarquez dans une extension peut être lu par l’utilisateur. Gardez la clé sur votre propre serveur, faites appeler votre serveur par l’extension, et laissez le serveur appeler la vraie API.

**Combien de temps dure la validation du Chrome Web Store ?** Il n’y a pas de délai fixe ; cela peut aller de quelques heures à plusieurs jours, parfois plus. Les extensions qui demandent de larges permissions ou embarquent du code minifié difficile à lire ont tendance à subir une revue plus détaillée.

**L’IA peut-elle convertir une extension Manifest V2 en Manifest V3 ?** Oui, les agents gèrent bien cette migration : page d’arrière-plan vers service worker, code distant dans le paquet, variables persistantes vers chrome.storage. Testez ensuite chaque fonction à la main, car l’arrêt du service worker change le comportement.

---

**À propos d’AgentVera.** AgentVera est une app de bureau pour macOS, Windows et Linux, développée par Solviera Teknoloji. Elle exécute 18 agents de code IA (Claude Code, Codex, Gemini CLI, Copilot, Cursor, Antigravity, opencode, Hermes, Qwen Code, Kimi Code, Kiro, Amp, Droid, Goose, Vibe, Crush, Aider, Cline) côte à côte, par projet, dans de vrais terminaux avec les installations et connexions CLI de l’utilisateur. L’offre gratuite inclut des agents illimités. Télécharger: https://agentvera.dev/fr/download/ · Tarifs: https://agentvera.dev/fr/pricing/
