Indexer vos pages hors connexion avec l'API Content Indexing

Permettre aux service workers d'indiquer aux navigateurs quelles pages fonctionnent hors connexion

Qu'est-ce que l'API Content Indexing ?

Utiliser une application Web progressive signifie avoir accès aux informations qui intéressent les utilisateurs (images, vidéos, articles, etc.), quel que soit l'état actuel de votre connexion réseau. Des technologies telles que les service workers, l'API Cache Storage et IndexedDB fournissent les éléments de base pour le stockage et la diffusion de données lorsque les utilisateurs interagissent directement avec une PWA. Mais la création d'une PWA de haute qualité et orientée hors connexion n'est qu'une partie de l'histoire. Si les utilisateurs ne se rendent pas compte que le contenu d'une application Web est disponible hors connexion, ils ne pourront pas tirer pleinement parti du travail que vous aurez fourni pour mettre en œuvre cette fonctionnalité.

Il s'agit d'un problème de découverte. Comment votre PWA peut-elle informer les utilisateurs de son contenu hors connexion afin qu'ils puissent découvrir et visualiser ce qui est disponible ? L'API Content Indexing est une solution à ce problème. La partie de cette solution destinée aux développeurs est une extension des service workers qui leur permet d'ajouter des URL et des métadonnées de pages hors connexion à un index local géré par le navigateur. Cette amélioration est disponible dans Chrome 84 et versions ultérieures.

Une fois que le contenu de votre PWA et de toute autre PWA installée a été inséré dans l'index, celui-ci est affiché par le navigateur, comme indiqué ci-dessous.

Capture d'écran de l'élément de menu "Téléchargements" sur la page "Nouvel onglet" de Chrome.
Tout d'abord, sélectionnez l'élément de menu Téléchargements sur la page "Nouvel onglet" de Chrome.
Médias et articles ayant été ajoutés à l'index.
Les médias et les articles qui ont été ajoutés à l'index s'afficheront dans la section Articles pour vous.

De plus, Chrome peut recommander de manière proactive du contenu lorsqu'il détecte que l'utilisateur est hors connexion.

L'API Content Indexing ne constitue pas une autre méthode pour mettre en cache du contenu. Il s'agit d'un moyen de fournir des métadonnées sur les pages déjà mises en cache par votre service worker, afin que le navigateur puisse afficher ces pages lorsque les utilisateurs sont susceptibles de vouloir les consulter. L'API Content Indexing aide à faciliter la découverte des pages mises en cache.

Démonstration

Le meilleur moyen de vous familiariser avec l'API Content Indexing est d'essayer un exemple d'application.

  1. Assurez-vous d'utiliser un navigateur et une plate-forme compatibles. Actuellement, cette fonctionnalité est limitée à Chrome 84 ou version ultérieure sur Android. Accédez à about://version pour connaître la version de Chrome que vous utilisez.
  2. Accédez à https://contentindex.dev.
  3. Cliquez sur le bouton + à côté d'un ou de plusieurs éléments de la liste.
  4. (Facultatif) Désactivez la connexion Wi-Fi et les données mobiles de votre appareil, ou activez le mode Avion pour simuler la mise hors connexion de votre navigateur.
  5. Sélectionnez Téléchargements dans le menu de Chrome, puis accédez à l'onglet Articles pour vous.
  6. Parcourez le contenu que vous avez enregistré.

Vous pouvez afficher la source de l'exemple d'application sur GitHub.

Un autre exemple d'application, une PWA de scrapbook, illustre l'utilisation de l'API Content Indexing avec l'API Web Share Target. Le code illustre une technique permettant de synchroniser l'API Content Indexing avec les éléments stockés par une application Web à l'aide de l'API Cache Storage.

Utiliser l'API

Pour utiliser l'API, votre application doit disposer d'un service worker et d'URL navigables hors connexion. Si votre application Web n'a pas encore de service worker, les bibliothèques Workbox peuvent simplifier la création d'un service worker.

Quels types d'URL peuvent être indexés comme pouvant être hors connexion ?

L'API prend en charge l'indexation des URL correspondant à des documents HTML. L'URL d'un fichier multimédia mis en cache, par exemple, ne peut pas être indexée directement. À la place, vous devez fournir l'URL d'une page qui affiche des contenus multimédias et fonctionne hors connexion.

Nous vous recommandons de créer une page HTML "viewer" (lecteur) pouvant accepter l'URL multimédia sous-jacente en tant que paramètre de requête, puis afficher le contenu du fichier, éventuellement avec des commandes ou du contenu supplémentaires sur la page.

Les applications Web ne peuvent ajouter à l'index de contenu que des URL qui relèvent du champ d'application du service worker actuel. En d'autres termes, une application Web ne pourrait pas ajouter à l'index de contenu une URL appartenant à un domaine complètement différent.

Présentation

L'API Content Indexing prend en charge trois opérations: ajouter, lister et supprimer des métadonnées. Ces méthodes sont exposées à partir d'une nouvelle propriété, index, qui a été ajoutée à l'interface ServiceWorkerRegistration.

La première étape de l'indexation du contenu consiste à obtenir une référence au ServiceWorkerRegistration actuel. navigator.serviceWorker.ready est la méthode la plus simple:

const registration = await navigator.serviceWorker.ready;

// Remember to feature-detect before using the API:
if ('index' in registration) {
  // Your Content Indexing API code goes here!
}

Si vous appelez l'API Content Indexing depuis un service worker plutôt que depuis une page Web, vous pouvez faire référence à ServiceWorkerRegistration directement via registration. Il sera déjà défini dans le ServiceWorkerGlobalScope..

Ajout à l'index

Utilisez la méthode add() pour indexer des URL et les métadonnées associées. C'est à vous de choisir à quel moment les éléments sont ajoutés à l'index. Vous pouvez ajouter des éléments à l'index en réponse à une entrée, par exemple en cliquant sur un bouton "Enregistrer hors connexion". Vous pouvez également ajouter des éléments automatiquement chaque fois que des données mises en cache sont mises à jour via un mécanisme comme la synchronisation périodique en arrière-plan.

await registration.index.add({
  // Required; set to something unique within your web app.
  id: 'article-123',

  // Required; url needs to be an offline-capable HTML page.
  url: '/articles/123',

  // Required; used in user-visible lists of content.
  title: 'Article title',

  // Required; used in user-visible lists of content.
  description: 'Amazing article about things!',

  // Required; used in user-visible lists of content.
  icons: [{
    src: '/img/article-123.png',
    sizes: '64x64',
    type: 'image/png',
  }],

  // Optional; valid categories are currently:
  // 'homepage', 'article', 'video', 'audio', or '' (default).
  category: 'article',
});

L'ajout d'une entrée n'affecte que l'index de contenu. Il n'ajoute rien au cache.

Cas limite: appeler add() à partir du contexte window si vos icônes reposent sur un gestionnaire fetch

Lorsque vous appelez add(), Chrome demande l'URL de chaque icône afin de s'assurer qu'il dispose d'une copie de l'icône à utiliser lors de l'affichage d'une liste de contenu indexé.

  • Si vous appelez add() à partir du contexte window (en d'autres termes, à partir de votre page Web), cette requête déclenchera un événement fetch sur votre service worker.

  • Si vous appelez add() dans votre service worker (éventuellement dans un autre gestionnaire d'événements), la requête ne déclenchera pas le gestionnaire fetch du service worker. Les icônes seront récupérées directement, sans aucune intervention du service worker. Gardez cela à l'esprit si vos icônes dépendent de votre gestionnaire fetch, peut-être parce qu'elles n'existent que dans le cache local et non sur le réseau. Si c'est le cas, assurez-vous de n'appeler add() qu'à partir du contexte window.

Afficher le contenu de l'index

La méthode getAll() renvoie une promesse pour une liste itérable d'entrées indexées et de leurs métadonnées. Les entrées renvoyées contiendront toutes les données enregistrées avec add().

const entries = await registration.index.getAll();
for (const entry of entries) {
  // entry.id, entry.launchUrl, etc. are all exposed.
}

Suppression d'éléments de l'index

Pour supprimer un élément de l'index, appelez delete() avec le id de l'élément à supprimer:

await registration.index.delete('article-123');

L'appel de delete() n'affecte que l'index. Elle ne supprime rien du cache.

Gérer un événement de suppression d'utilisateur

Lorsque le navigateur affiche le contenu indexé, il peut inclure sa propre interface utilisateur avec un élément de menu Supprimer, ce qui permet aux utilisateurs d'indiquer qu'ils ont terminé de consulter le contenu précédemment indexé. Voici à quoi ressemble l'interface de suppression dans Chrome 80:

Élément de menu de suppression.

Lorsqu'un utilisateur sélectionne cet élément de menu, le service worker de votre application Web reçoit un événement contentdelete. Bien que la gestion de cet événement soit facultative, elle permet à votre service worker de "nettoyer" le contenu, tel que les fichiers multimédias mis en cache localement, que quelqu'un a indiqué comme ayant terminé.

Vous n'avez pas besoin d'appeler registration.index.delete() dans votre gestionnaire contentdelete. Si l'événement a été déclenché, le navigateur a déjà effectué la suppression d'index appropriée.

self.addEventListener('contentdelete', (event) => {
  // event.id will correspond to the id value used
  // when the indexed content was added.
  // Use that value to determine what content, if any,
  // to delete from wherever your app stores it—usually
  // the Cache Storage API or perhaps IndexedDB.
});

Commentaires sur la conception de l'API

Y a-t-il un élément de l'API qui est gênant ou ne fonctionne pas comme prévu ? Ou manque-t-il des éléments dont vous avez besoin pour mettre en œuvre votre idée ?

Signalez un problème dans le dépôt GitHub d'explication de l'API Content Indexing ou faites part de vos commentaires à un problème existant.

Un problème d'implémentation ?

Avez-vous détecté un bug dans l'implémentation de Chrome ?

Signalez un bug à l'adresse https://new.crbug.com. Fournissez autant de détails que possible, fournissez des instructions simples pour reproduire le problème, puis définissez Composants sur Blink>ContentIndexing.

Vous prévoyez d'utiliser l'API ?

Vous prévoyez d'utiliser l'API Content Indexing dans votre application Web ? Votre assistance publique aide Chrome à hiérarchiser les fonctionnalités et montre aux autres fournisseurs de navigateurs à quel point il est essentiel de les prendre en charge.

Quelles sont les implications de l'indexation de contenu en termes de sécurité et de confidentialité ?

Consultez les réponses fournies en réponse au questionnaire sur la sécurité et la confidentialité du W3C. Si vous avez d'autres questions, veuillez démarrer une discussion via le dépôt GitHub du projet.

Image principale de Maksym Kaharlytskyi sur Unsplash.