Créer une extension Chrome de notes Pinterest

Salo Par Salo 5 min de lecture
Créer une extension Chrome de notes Pinterest

Ce tutoriel construit le plus petit prototype utile sous Chrome Manifest V3 : une zone de texte privée intégrée aux pages d’Épingle Pinterest, indexée par l’identifiant numérique de l’Épingle et enregistrée dans chrome.storage.local. Il s’agit volontairement d’un prototype, pas d’une réplique des anciennes notes Pinterest prête pour la production.

Le DOM de Pinterest peut changer sans préavis. Isolez vos sélecteurs, n’imitez pas les éléments de marque protégés de Pinterest et testez tous les types de pages et toutes les langues que vous annoncez prendre en charge.

1. Créez l’extension Manifest V3

Créez un dossier contenant manifest.json et content.js. La documentation de référence du manifeste Chrome fait autorité pour les clés disponibles.

{ "manifest_version": 3, "name": "Prototype de contexte d’Épingle", "version": "0.1.0", "description": "Enregistre une note privée locale pour une Épingle Pinterest.", "permissions": ["storage"], "content_scripts": [{ "matches": ["https://*.pinterest.com/*"], "js": ["content.js"], "run_at": "document_idle" }] }

Le motif d’hôte est large, car Pinterest utilise une navigation côté client. Si votre fonctionnalité ne prend en charge qu’un nombre limité de routes ou de domaines nationaux, réduisez ce périmètre et documentez-le.

2. Dérivez une clé stable de l’URL de l’Épingle

N’utilisez ni la position d’une carte ni son titre visible comme clé de note. Extrayez l’identifiant numérique d’un chemin canonique /pin/…/ et renvoyez null dans tous les autres cas.

function getPinId(url = location.href) { try { const { pathname } = new URL(url); const match = pathname.match(/\/pin\/(\d+)\/?/); return match ? match[1] : null; } catch { return null; } }

Testez les URL de détail valides, les chaînes de requête, les pages sans Épingle, les URL mal formées et toutes les variantes locales que vous annoncez prendre en charge. N’associez jamais silencieusement une note lorsque l’identifiant est incertain.

3. Stockez un enregistrement versionné

Définissez explicitement le schéma afin de permettre les futures migrations :

async function readNote(pinId) { const key = 'pin-note:' + pinId; const result = await chrome.storage.local.get(key); return result[key] ?? { version: 1, pinId, text: '', updatedAt: null }; } async function writeNote(pinId, text) { const key = 'pin-note:' + pinId; const record = { version: 1, pinId, text, updatedAt: new Date().toISOString() }; await chrome.storage.local.set({ [key]: record }); return record; }

Chrome documente une limite par défaut de 10 Mo pour storage.local, ainsi qu’une autorisation distincte, unlimitedStorage , qui permet d’augmenter cette capacité. Chrome précise également que le stockage local de l’extension est effacé lors de sa désinstallation. Consultez la version actuelle de la documentation de l’API Storage et concevez l’export avant d’encourager les utilisateurs à confier des données importantes à l’extension.

4. Intégrez un éditeur isolé et accessible

Un Shadow DOM limite les collisions de styles accidentelles. L’exemple ajoute le composant au corps de la page afin de ne pas dépendre d’un nom de classe Pinterest fragile :

async function mountEditor(pinId) { if (document.querySelector('[data-pin-context-root]')) return; const host = document.createElement('aside'); host.dataset.pinContextRoot = ''; host.setAttribute('aria-label', 'Note privée pour une Épingle'); document.body.append(host); const root = host.attachShadow({ mode: 'open' }); const label = document.createElement('label'); label.textContent = 'Note privée'; const editor = document.createElement('textarea'); editor.id = 'pin-note-editor'; label.htmlFor = editor.id; editor.setAttribute('aria-label', 'Note privée pour cette Épingle'); const status = document.createElement('span'); status.setAttribute('role', 'status'); const saved = await readNote(pinId); editor.value = saved.text; root.append(label, editor, status); bindAutosave(editor, status, pinId); }

Créez le texte de l’interface avec textContent, jamais avec du contenu non fiable injecté dans innerHTML. Ajoutez un indicateur de focus visible, un contraste suffisant, un véritable libellé, un accès complet au clavier et un texte d’état qui ne déplace pas le focus.

5. Enregistrez sans écrire à chaque frappe

function bindAutosave(editor, status, pinId) { let saveTimer; editor.addEventListener('input', () => { status.textContent = 'Non enregistré'; clearTimeout(saveTimer); saveTimer = setTimeout(async () => { try { await writeNote(pinId, editor.value); status.textContent = 'Enregistré localement'; } catch (error) { console.error('Échec de l’enregistrement de la note', error); status.textContent = 'Enregistrement impossible'; } }, 400); }); }

En production, forcez également l’enregistrement des saisies en attente lors d’un changement de page, empêchez deux onglets de s’écraser mutuellement, fixez une taille maximale pour les notes et affichez clairement les erreurs de quota.

6. Gérez la navigation côté client de Pinterest

Un gestionnaire exécuté uniquement au chargement ne détecte pas la navigation entre le fil et les pages de détail. Utilisez une fonction de réconciliation idempotente et observez les changements sans recréer le composant à chaque mutation :

let scheduled = false; async function reconcile() { scheduled = false; const pinId = getPinId(); const existing = document.querySelector('[data-pin-context-root]'); if (!pinId) { existing?.remove(); return; } if (existing?.dataset.pinId === pinId) return; existing?.remove(); await mountEditor(pinId); const mounted = document.querySelector('[data-pin-context-root]'); if (mounted) mounted.dataset.pinId = pinId; } new MutationObserver(() => { if (scheduled) return; scheduled = true; requestAnimationFrame(reconcile); }).observe(document.documentElement, { childList: true, subtree: true }); reconcile();

Une version de production doit aussi surveiller directement l’état de navigation lorsque c’est possible et déconnecter les observateurs devenus inutiles. Mesurez les performances du code sur de longs fils : une fonction correcte qui ralentit la page reste une mauvaise extension.

7. Respectez les contraintes de sécurité de Manifest V3

Manifest V3 interdit le code exécutable hébergé à distance. Intégrez tout le JavaScript exécutable à l’extension, conservez la politique de sécurité du contenu par défaut sauf raison justifiée de la modifier, évitez l’exécution dynamique de code et ne demandez que les autorisations indispensables. La présentation de Manifest V3 par Chrome explique le modèle de la plateforme.

8. Ajoutez les fonctions nécessaires à un véritable produit

9. Testez les scénarios d’échec

  1. Chargez l’extension non empaquetée depuis chrome://extensions.
  2. Ouvrez un fil, un tableau, une page de détail d’Épingle et une route qui ne correspond pas à une Épingle.
  3. Passez d’une Épingle à une autre sans recharger la page et vérifiez que leurs notes restent isolées.
  4. Ouvrez la même Épingle dans deux onglets et testez la gestion des conflits.
  5. Désactivez le stockage ou simulez un dépassement de quota, puis vérifiez l’avertissement.
  6. Exportez un enregistrement de test, supprimez-le, puis restaurez-le.
  7. Testez la navigation au clavier, le zoom, les libellés pour lecteurs d’écran ainsi que les thèmes clair et sombre de la page.

La leçon d’ingénierie

La zone de texte est la partie facile. Une extension Pinterest digne de confiance repose sur un identifiant stable, une gestion robuste du cycle de vie, une interface accessible, des autorisations limitées, un stockage documenté et une procédure de sortie testée. Construisez ces fondations avant d’allonger la liste des fonctions.

Continuez à améliorer votre organisation sur Pinterest

Poursuivez avec le guide qui correspond à votre prochaine étape :

Salo

À propos de l'auteur

Salo est designer produit et utilisateur expérimenté. Il écrit sur l'organisation numérique, les méthodes de travail sur Pinterest et les outils qui aident à mieux réfléchir.

Essayez l'extension Notestopin pour Chrome

Ajoutez des notes privées à chaque épingle, classez-les avec des tags et retrouvez facilement vos contenus enregistrés.

Ajouter à Chrome