CommunityRédaction et éditiongithub.com

erberkk/présence-web-et-référencement

À utiliser lors de la construction, de la vérification ou du déploiement du site web nécessaire aux fiches des magasins d'applications et au lancement : pages de politique de confidentialité, conditions, support et suppression de compte fonctionnant sans connexion ; hébergement de apple-app-site-association et assetlinks.json ; pages d'invitation/parrainage (/i/<code>) qui ouvrent l'application ou renvoient vers le magasin avec le référent d'installation Play ; une page d'accueil avec les badges des magasins et des prix honnêtes par pays renseignés à la volée ; images Open Graph ; SEO technique (hreflang, canonique, sitemap, robots.txt, JSON-LD) ; Search Console, Bing Webmaster et IndexNow ; politique des robots d'IA et llms.txt ; et un déploiement Cloudflare Worker avec une porte d'approbation de production. Inclut un vérificateur de site et un script de ping IndexNow.

Qu'est-ce que présence-web-et-référencement ?

Cette compétence construit un site statique petit et rapide qui satisfait d'abord aux exigences des magasins d'applications (Apple App Store et Google Play), puis le rend trouvable par les moteurs de recherche, les aperçus de liens et les assistants IA. Elle gère les pages obligatoires comme la politique de confidentialité, les conditions d'utilisation, le support et la suppression de compte, ainsi que les fichiers `.well-known` pour les liens d'application. Elle inclut des pages d'invitation/parrainage qui ouvrent l'application si installée ou redirigent vers le magasin. La compétence est conçue pour fonctionner avec Cloudflare Workers, mais peut s'adapter à d'autres hébergeurs. Elle comprend des vérifications de référencement technique automatisées (hreflang, sitemap, robots.txt, JSON-LD) et des scripts de vérification pour garantir que le site est correctement déployé et indexé. Les points de décision nécessitant une approbation humaine sont clairement identifiés, notamment pour les déploiements en production, les modifications DNS, le contenu des pages légales et les paramètres des robots d'IA.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/erberkk/mobile-app-launch-skills/tree/HEAD/skills/web-presence-and-seo

Installed? Explore more Rédaction et édition skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Présence Web et Référencement

Objectif

Les deux magasins demandent des URL avant de permettre la soumission : politique de confidentialité, support, suppression de compte, et pour les liens d'application les fichiers .well-known. Cette compétence construit un petit site statique rapide qui satisfait d'abord à ces formulaires, puis le rend trouvable (moteurs de recherche, aperçus de liens, assistants IA) sans traceurs, motifs sombres ou chiffres que l'application ne peut pas étayer.

Faites cela avant les formulaires de fiche de magasin et de confidentialité (listing-and-aso, privacy-and-declarations) : ils ont besoin d'URL en direct.

Prérequis

  • Un domaine que vous contrôlez, avec accès DNS (Cloudflare est utilisé dans les exemples ; n'importe quel hébergeur fonctionne s'il peut définir des en-têtes et servir des fichiers sans redirections).
  • Les identifiants finaux de l'application et les données de signature de identity-and-signing (Team ID, bundle ID, nom du package, SHA-256 de la signature d'application Play).
  • Le texte de la politique de confidentialité dérivé de l'analyse du code/SDK (privacy-and-declarations) et le flux de suppression qui existe réellement dans l'application.
  • Les prix lus depuis les magasins (subscriptions-and-payments), jamais tapés de mémoire.
  • Node.js 18+ pour les scripts dans scripts/.

1. Pages requises par les magasins

Liste de contrôle avec chaque champ de magasin → URL : references/store-url-checklist.md.

PageChemin (suggéré)Règles
Politique de confidentialité/privacyPublique, sans connexion, sans blocage géographique, HTML (pas PDF), nomme l'application, correspond aux réponses de confidentialité du magasin
Conditions/termsNécessaire si vous vendez des abonnements (CLUF standard d'Apple ou le vôtre ; liez-le dans l'application et la fiche)
Support / contact/supportUn vrai moyen de vous joindre (email ou formulaire), pas seulement une FAQ
Suppression de compte (web)/delete-accountGoogle Play exige cette URL. Nomme l'application comme sur la fiche, permet à l'utilisateur de demander la suppression depuis la page elle-même, indique ce qui est supprimé, ce qui est conservé et pendant combien de temps, et qu'un abonnement au magasin doit être annulé séparément
  • Apple exige que la suppression commence dans l'application (directive 5.1.1(v)) ; une page web ne remplace pas cela. Play exige à la fois le chemin dans l'application et l'URL web. Docs : Suppression de compte Apple, Suppression de compte Play, Règles d'URL de politique de confidentialité Play.
  • Sans connexion et stable. Pas de mur de cookies, pas de connexion, pas de JavaScript nécessaire pour lire le texte. Ne renommez pas les chemins après la soumission ; si vous devez le faire, conservez une redirection 301 depuis l'ancien chemin.
  • Par langue. Une URL par langue (/privacy, /de/privacy) avec hreflang ; App Store Connect permet de définir une URL de confidentialité par localisation. Si une page n'est pas traduite, liez la page de la langue par défaut plutôt qu'une 404.
  • Affichez la date de "dernière mise à jour" sur les pages juridiques et conservez les anciennes versions dans le contrôle de version.

2. Hébergement des liens d'application

Les modèles pour les fichiers eux-mêmes se trouvent dans identity-and-signing/templates/. Cette section concerne leur service.

  • https://<domaine>/.well-known/apple-app-site-association et /.well-known/assetlinks.json : HTTP 200, Content-Type: application/json, aucune redirection (pas http→https, pas apex→www, pas de barre oblique finale), pas d'authentification, pas de page de défi bot.
  • Décidez apex vs www une fois pour toutes. Servez les fichiers sur chaque hôte listé dans les entitlements / filtres d'intent ; redirigez l'autre hôte pour les pages uniquement, jamais pour /.well-known/.
  • Les hébergeurs statiques servent souvent le fichier AASA sans extension comme application/octet-stream. Routez /.well-known/* via le Worker (voir le modèle) ou définissez l'en-tête explicitement, puis vérifiez avec scripts/check-site.mjs.
  • Déployez les fichiers .well-known avant la compilation de l'application qui revendique le domaine. Apple récupère AASA via son CDN, donc les changements peuvent prendre du temps à apparaître.

Pages d'invitation / parrainage (/i/<code>)

  • Le Worker valide le code par rapport à l'alphabet exact et à la longueur émis par le backend, puis remplit un modèle. Rien d'autre de l'URL n'atteint le HTML.
  • Si l'application est installée, les liens universels / App Links l'ouvrent directement (le chemin doit être dans les components d'AASA et le filtre d'intent Android). Sinon, la page affiche les deux boutons de magasin et un bouton "copier le code" comme solution de repli manuelle.
  • Android : ajoutez le code à l'URL Play sous la forme &referrer=<key=value encodé en URL> et lisez-le dans l'application avec l'API Play Install Referrer. iOS n'a pas de référent d'installation ; demandez à l'utilisateur de coller le code, ou préremplissez-le depuis le presse-papiers uniquement après un appui explicite.
  • En-têtes : X-Robots-Tag: noindex, Cache-Control: private, no-store, Referrer-Policy: no-referrer. Gardez /i/ hors du sitemap. Ne le Disallow pas dans robots.txt : un robot qui ne peut pas récupérer la page ne voit jamais le noindex.

3. Page d'accueil

  • Même langage visuel que les captures d'écran du magasin (couleurs, typographie, les mêmes cartes UI réelles). Un visiteur arrivant du site devrait reconnaître la page du magasin.
  • Badges des magasins uniquement dans les œuvres officielles, non modifiés, avec l'espacement et le libellé requis ; lien direct vers la fiche. Règles : Directives marketing Apple, Badges Google Play.
  • Avant le lancement : une ligne "Bientôt disponible sur l'App Store et Google Play", pas trois badges désactivés. Au lancement (après la publication en direct) : remplacez par de vrais liens de badges, ajoutez la balise Smart App Banner (docs), mettez à jour llms.txt et le JSON-LD. Gardez cela comme un seul indicateur de configuration pour que ce soit un seul changement. APPROBATION avant de basculer.
  • Prix honnêtes. Les prix proviennent d'un fichier généré à partir de la relecture du magasin. Les pages contiennent des espaces réservés (%%PRICE_MONTHLY%%) ; le Worker les remplit par pays du visiteur (request.cf.country) et indique "le magasin affiche le prix exact dans votre devise" pour les pays hors tableau. La langue de la page ne décide jamais de la devise. Pas de prix "était" barrés, pas de faux comptes à rebours, pas de cases pré-cochées.
  • Rapide et accessible. Texte en HTML (pas rendu par JS), un fichier CSS, peu ou pas de JS, polices auto-hébergées avec font-display: swap, image de héros dimensionnée avec fetchpriority="high". Objectifs : LCP < 2,5 s, CLS < 0,1, INP < 200 ms (Web Vitals). Contraste et états de focus selon WCAG 2.2 ; prefers-reduced-motion respecté.
  • Analytiques. Préférez aucun ou des comptages serveur/sans cookies (journaux de périphérie, analytiques respectueuses de la vie privée sans identifiants). Si vous ne définissez aucun cookie et ne chargez aucun script tiers, vous n'avez pas besoin de bannière de cookies ; n'en affichez pas "au cas où". Si vous ajoutez un traceur, la bannière de consentement, la politique de confidentialité et les réponses de confidentialité du magasin doivent toutes changer ensemble.

4. Images de partage social

  • Une image Open Graph par langue : 1200×630 PNG/JPG, sous ~1 Mo, texte suffisamment grand pour être lu en taille de vignette. URL https:// absolues dans og:image et twitter:image, plus og:image:width/height/alt, og:title, og:description, og:url, twitter:card=summary_large_image. Spécification : ogp.me, Guide de partage Meta.
  • Les applications de messagerie mettent en cache les aperçus de manière agressive. Après avoir modifié une image, donnez-lui un nouveau nom de fichier (ou ?v=2), puis re-scrapez dans le Sharing Debugger ("Scrape Again"). WhatsApp et autres messageries conservent leurs propres caches sans outil de rafraîchissement public, donc une nouvelle URL d'image est la solution fiable ; testez en envoyant le lien dans une nouvelle conversation.

5. SEO technique

  • Titre (≈50–60 caractères, marque + ce qu'elle fait) et méta-description (≈150–160 caractères) uniques par page et par langue. Liens titre, extraits.
  • hreflang : chaque version linguistique liste toutes les versions y compris elle-même, plus x-default ; les paires doivent être réciproques. Versions localisées.
  • Canonique : auto-référençant, absolu, sur l'URL finale (sans redirection). Canonicalisation.
  • Sitemap avec uniquement des URL 200, indexables, canoniques et un <lastmod> réel (date à laquelle le contenu a changé, par exemple depuis git, pas l'heure de compilation). Modèle, docs.
  • robots.txt : modèle, intro. robots.txt contrôle le crawling, pas l'indexation ; utilisez noindex pour les pages qui doivent rester hors des résultats.
  • Données structurées (JSON-LD) : Organization, WebSite, MobileApplication ; FAQPage uniquement pour une FAQ visible sur la page. Exemples et règles : references/structured-data.md.
  • Les hôtes non-production (aperçu, *.workers.dev) envoient X-Robots-Tag: noindex.

6. Découverte

  1. Google Search Console : ajoutez une propriété Domaine, ajoutez l'enregistrement TXT google-site-verification à l'apex, vérifiez, soumettez le sitemap, demandez l'indexation pour les pages d'accueil. Vérifier la propriété.
  2. Bing Webmaster Tools : importez depuis Search Console, ou vérifiez avec l'enregistrement DNS que Bing donne (un CNAME), puis soumettez le sitemap. Ajouter et vérifier.
  3. IndexNow (Bing, Yandex, Seznam, Naver et autres ; pas Google) : hébergez /<clé>.txt contenant la clé, déployez, puis exécutez node scripts/indexnow-ping.mjs (simulation) et --send. Le script vérifie d'abord que le fichier de clé est en direct. Protocole.
  4. Robots d'IA et llms.txt : décidez par bot s'il faut autoriser les bots de recherche/réponse et les bots d'entraînement (décision du propriétaire, APPROBATION). Liste des bots, objectifs et liens officiels : references/ai-crawlers.md. Ajoutez un court llms.txt avec le résumé du produit et les URL clés, sans prix.

Les enregistrements DNS sont une infrastructure partagée : ajoutez le nouvel enregistrement ; ne modifiez ni ne supprimez jamais les enregistrements TXT/SPF/MX existants. APPROBATION avant tout changement DNS.

7. Déploiement (exemple Cloudflare Worker)

Modèle : templates/worker.example.js. Il sert les fichiers .well-known avec le bon type et sans redirection, remplit les espaces réservés de prix par pays, rend /i/<code>, ajoute les en-têtes de sécurité et noindex sur les hôtes non-production.

Deux options de stockage :

  • Workers Static Assets (le plus simple) : "assets": { "directory": "./dist", "binding": "ASSETS", "run_worker_first": true } dans wrangler.jsonc ; le Worker appelle env.ASSETS.fetch(). Docs.
  • KV (adressé par contenu) : la compilation écrit les fichiers sous leur hash et un manifest.js (chemin → hash, type) ; téléchargez avec wrangler kv bulk put avant de déployer le Worker, afin que le nouveau manifeste ne pointe jamais vers un fichier manquant. Commandes KV.

Étapes :

  1. node build.mjs → dist/ (échoue en cas de clé de traduction manquante ou d'espace réservé non rempli autre que ceux de prix).
  2. Tests unitaires (node --test) : exécutez le fetch du Worker contre des actifs factices. Couvrez : AASA/assetlinks 200 + application/json + pas de redirection ; redirection www/http pour les pages uniquement ; /i/<mauvais> → 404, /i/<bon> → noindex + no-store ; chaque région de prix remplit tous les espaces réservés (aucun %% restant) ; encodage de pourcentage malformé → 404, pas 500.
  3. Aperçu : npx wrangler deploy --dry-run, ou déployez sur un hôte d'aperçu et exécutez node scripts/check-site.mjs https://<hôte-d-aperçu>.
  4. APPROBATION — déploiement de production (npx wrangler deploy). Épinglez account_id, name et routes dans wrangler.jsonc pour que la commande ne puisse pas cibler un autre projet sur un compte partagé.
  5. Après déploiement : node scripts/check-site.mjs https://example.com --invite <code d'exemple>, puis le ping IndexNow.

Points de décision nécessitant une approbation humaine

  • Déploiements de production et modifications DNS.
  • Libellé des pages juridiques (confidentialité, conditions, suppression) ; le propriétaire approuve tout changement.
  • Autorisation/interdiction des robots d'entraînement d'IA.
  • Le passage "bientôt disponible" → "télécharger" et tout prix affiché sur le site.
  • Ajout d'analytiques, d'un formulaire de liste d'attente ou de tout ce qui collecte des données personnelles.

Vérification

  • node scripts/check-site.mjs https://example.com --paths /privacy,/terms,/support,/delete-account se termine avec 0 : pages requises 200 sans connexion, AASA/assetlinks JSON sans redirection, balises OG avec images absolues accessibles, hreflang réciproque, URL du sitemap toutes 200.
  • Chaque URL dans la liste de contrôle store-url s'ouvre dans une fenêtre privée sur un téléphone.
  • Rich Results Test et Schema Markup Validator ne montrent aucune erreur ; PageSpeed Insights mobile LCP < 2,5 s.
  • Search Console : sitemap "Succès" ; Bing : soumissions IndexNow visibles.

Pièges courants

  • URL de confidentialité qui redirige vers une connexion, un PDF ou une politique d'entreprise générique qui ne nomme jamais l'application.
  • Page de suppression qui dit seulement "supprimer dans l'application" (Play veut un chemin de demande sur la page) ou oublie de mentionner l'annulation de l'abonnement au magasin.
  • AASA servi via une redirection apex→www, en text/html, ou derrière un défi bot.
  • Disallow: /i/ dans robots.txt combiné avec un en-tête noindex que les robots ne voient alors jamais.
  • Prix codés en dur par langue (EUR sur la page allemande pour un visiteur en Suisse) ou laissés comme des nombres obsolètes après un changement de prix du magasin.
  • aggregateRating inventé pour une nouvelle application, ou offers avec un prix qui n'est vrai que dans un seul pays.
  • Image OG avec une URL relative dans un aperçu de messagerie, ou un og:image qui renvoie une 404.
  • hreflang manquant sur les pages de suppression/compte, ou page en français listant l'espagnol mais pas l'inverse.
  • Enregistrements DNS supprimés au lieu d'ajoutés (SPF/DKIM/courrier perdu).
  • Scripts de construction qui échouent sur un espace réservé inattendu, mais que personne ne remarque avant la prochaine vérification.

Références

RéférenceLien
Modèle de Workertemplates/worker.example.js
Exemple de Sitemaptemplates/sitemap.example.xml
Exemple de llms.txttemplates/llms.example.txt
Liste de contrôle des URL de magasinreferences/store-url-checklist.md
Données structuréesreferences/structured-data.md
Robots d'IAreferences/ai-crawlers.md
Script de vérification du sitescripts/check-site.mjs
Script de ping IndexNowscripts/indexnow-ping.mjs
Script de constructionscripts/build.mjs (selon package.json)

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

erberkk/privacy-and-declarations

Use when filling in or auditing App Store privacy and compliance answers and Google Play App content declarations - Apple App Privacy labels, Play Data safety (CSV import), Health apps declaration and Health Connect permissions, advertising ID, PrivacyInfo.xcprivacy and required-reason APIs, export compliance (ITSAppUsesNonExemptEncryption), age rating, account deletion (in-app, web URL, re-authentication), consent and disclosure for AI features, and rules for health data. Derives every answer from a code and SDK scan so the forms, the privacy policy and the in-app text say the same thing.

erberkk/review-readiness

Use before submitting an app version or a first subscription for App Store or Google Play review, or after receiving a rejection. Runs a go/no-go checklist and writes a report - demo account that signs in with a password (no email one-time code), filled with data and premium unlocked; review notes; in-app purchases visible and purchasable (guideline 2.1(b)); iPad compatibility mode for iPhone-only apps; no placeholders or "coming soon"; metadata matching the app; live privacy URLs; crash-free cold start - and gives a playbook for replying in Resolution Center and deciding when to appeal.

erberkk/social-publishing

Use when setting up scheduled publishing of an app's marketing content to Instagram (Reels, carousels, Stories), Threads, X and TikTok through official APIs - self-hosting Postiz in Docker behind a Cloudflare Tunnel, creating the Meta app with the newer use-case flow (business portfolio, Facebook Page linked to the Instagram professional account, Threads tester invite), X developer pay-per-use credits and spend cap, TikTok and YouTube audit limits, safe OAuth account selection when one browser holds personal and brand accounts, resource limits, and phasing a posting calendar around real launch events.

erberkk/store-screenshots

Use when producing or updating App Store and Google Play screenshots and the Play feature graphic - planning a connected "panorama" story across frames, capturing real in-app screens with the app's own test/screenshot harness at each device's logical size and pixel ratio, covering the full device matrix (iPhone 6.9", the required medium Dynamic Island slot, iPhone Duo outer and inner displays, iPad 13" if the app runs on iPad, Play phone, 7" and 10" tablets, 1024x500 feature graphic), checking for alpha channels and wrong sizes, and uploading in order via the App Store Connect and Google Play APIs.

Skills associés