Indicizzare le pagine compatibili con la modalità offline con l'API Content Indexing

Consentire ai worker di servizio di indicare ai browser quali pagine funzionano offline

Che cos'è l'API Content Indexing?

L'utilizzo di un'app web progressiva significa avere accesso alle informazioni che interessano alle persone, come immagini, video, articoli e altro ancora, indipendentemente dallo stato attuale della connessione di rete. Tecnologie come i service worker, l'API Cache Storage e IndexedDB ti forniscono gli elementi di base per archiviare e pubblicare i dati quando gli utenti interagiscono direttamente con una PWA. Tuttavia, creare una PWA di alta qualità incentrata sull'offline è solo una parte della storia. Se gli utenti non sanno che i contenuti di un'app web sono disponibili offline, non sfruttano appieno il lavoro che hai svolto per implementare questa funzionalità.

Si tratta di un problema di rivelazione: come può la tua PWA informare gli utenti dei suoi contenuti supportati offline in modo che possano scoprire e visualizzare ciò che è disponibile? L'API Content Indexing è una soluzione a questo problema. La parte rivolta agli sviluppatori di questa soluzione è un'estensione dei service worker, che consente agli sviluppatori di aggiungere URL e metadati di pagine compatibili con la modalità offline a un indice locale gestito dal browser. Questo miglioramento è disponibile in Chrome 84 e versioni successive.

Una volta che l'indice è stato compilato con i contenuti della tua PWA e di tutte le altre PWA installate, verrà visualizzato dal browser come mostrato di seguito.

Uno screenshot dell'elemento di menu Download nella pagina Nuova scheda di Chrome.
Innanzitutto, seleziona l'elemento di menu Download nella pagina Nuova scheda di Chrome.
Contenuti multimediali e articoli aggiunti all'indice.
I contenuti multimediali e gli articoli aggiunti all'indice verranno mostrati nella sezione Articoli per te.

Inoltre, Chrome può consigliare in modo proattivo i contenuti quando rileva che un utente è offline.

L'API Content Indexing non è un modo alternativo per memorizzare nella cache i contenuti. È un modo per fornire metadati sulle pagine già memorizzate nella cache dal tuo servizio worker, in modo che il browser possa mostrarle quando è probabile che gli utenti vogliano visualizzarle. L'API Content Indexing contribuisce alla visibilità delle pagine memorizzate nella cache.

Guarda come funziona

Il modo migliore per farsi un'idea dell'API Content Indexing è provare un'applicazione di esempio.

  1. Assicurati di utilizzare un browser e una piattaforma supportati. Al momento, questa funzionalità è limitata a Chrome 84 o versioni successive su Android. Vai a about://version per vedere la versione di Chrome in uso.
  2. Visita la pagina https://contentindex.dev.
  3. Fai clic sul pulsante + accanto a uno o più elementi dell'elenco.
  4. (Facoltativo) Disattiva la connessione Wi-Fi e la rete dati del dispositivo oppure attiva la modalità aereo per simulare il passaggio del browser alla modalità offline.
  5. Scegli Download dal menu di Chrome e passa alla scheda Articoli per te.
  6. Sfoglia i contenuti salvati in precedenza.

Puoi visualizzare il codice sorgente dell'applicazione di esempio su GitHub.

Un'altra applicazione di esempio, una PWA Scrapbook, illustra l'utilizzo dell'API Content Indexing con l'API Target di condivisione web. Il codice mostra una tecnica per mantenere sincronizzata l'API Content Indexing con gli elementi archiviati da un'app web utilizzando l'API Cache Storage.

Utilizzo dell'API

Per utilizzare l'API, la tua app deve avere un servizio worker e URL navigabili offline. Se la tua app web non ha attualmente un servizio worker, le librerie Workbox possono semplificarne la creazione.

Quali tipi di URL possono essere indicizzati come compatibili con l'utilizzo offline?

L'API supporta l'indicizzazione degli URL corrispondenti ai documenti HTML. Ad esempio, un URL per un file multimediale memorizzato nella cache non può essere indicizzato direttamente. Devi invece fornire un URL di una pagina che mostri contenuti multimediali e che funzioni offline.

Un pattern consigliato è creare una pagina HTML "visualizzatore" che possa accettare l'URL del media sottostante come parametro di query e poi visualizzare i contenuti del file, potenzialmente con controlli o contenuti aggiuntivi nella pagina.

Le app web possono aggiungere all'indice dei contenuti solo gli URL che rientrano nell'ambito del service worker corrente. In altre parole, un'app web non poteva aggiungere un URL appartenente a un dominio completamente diverso all'indice dei contenuti.

Panoramica

L'API Content Indexing supporta tre operazioni: aggiunta, elencazione e rimozione di metadati. Questi metodi sono esposti da una nuova proprietà, index, che è stata aggiunta all'interfaccia ServiceWorkerRegistration.

Il primo passaggio per indicizzare i contenuti consiste nell'ottenere un riferimento all'ServiceWorkerRegistration corrente. L'utilizzo di navigator.serviceWorker.ready è il modo più semplice:

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!
}

Se effettui chiamate all'API Content Indexing da un servizio worker, piuttosto che all'interno di una pagina web, puoi fare riferimento a ServiceWorkerRegistration direttamente tramite registration. È già definito come parte del ServiceWorkerGlobalScope.

Aggiunta all'indice

Utilizza il metodo add() per indicizzare gli URL e i relativi metadati associati. Sta a te scegliere quando aggiungere gli elementi all'indice. Potresti voler aggiungere elementi all'indice in risposta a un input, ad esempio facendo clic su un pulsante "Salva offline". In alternativa, puoi aggiungere elementi automaticamente ogni volta che i dati memorizzati nella cache vengono aggiornati tramite un meccanismo come la sincronizzazione in background periodica.

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'aggiunta di una voce interessa solo l'indice dei contenuti e non aggiunge nulla alla cache.

Caso limite: chiama add() dal contesto window se le icone si basano su un gestore fetch

Quando chiami add(), Chrome invia una richiesta per l'URL di ogni icona per assicurarsi di avere una copia dell'icona da utilizzare quando viene visualizzato un elenco di contenuti indicizzati.

  • Se chiami add() dal contesto window (in altre parole, dalla pagina web), questa richiesta attiverà un evento fetch nel tuo service worker.

  • Se chiami add() all'interno del tuo service worker (ad esempio all'interno di un altro gestore di eventi), la richiesta non attiverà il gestore fetch del service worker. Le icone verranno recuperate direttamente, senza il coinvolgimento del service worker. Tieni conto di questo se le tue icone si basano sull'handler fetch, ad esempio perché esistono solo nella cache locale e non sulla rete. In questo caso, assicurati di chiamare add() solo dal contesto window.

Elenco dei contenuti dell'indice

Il metodo getAll() restituisce una promessa per un elenco iterabile di voci indicizzate e dei relativi metadati. Le voci restituite conterranno tutti i dati salvati con add().

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

Rimozione di elementi dall'indice

Per rimuovere un elemento dall'indice, chiama delete() con il id dell'elemento da rimuovere:

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

La chiamata a delete() influisce solo sull'indice. Non viene eliminato alcun dato dalla cache.

Gestione di un evento di eliminazione utente

Quando il browser mostra i contenuti indicizzati, potrebbe includere la propria interfaccia utente con un elemento di menu Elimina, che consente agli utenti di indicare che hanno terminato di visualizzare i contenuti indicizzati in precedenza. Questo è l'aspetto dell'interfaccia di eliminazione in Chrome 80:

La voce di menu Elimina.

Quando un utente seleziona l'elemento di menu, il service worker della tua app web riceve un evento contentdelete. Sebbene la gestione di questo evento sia facoltativa, offre al tuo service worker la possibilità di "ripulire" i contenuti, ad esempio i file multimediali memorizzati nella cache locale, di cui qualcuno ha indicato di non aver più bisogno.

Non è necessario chiamare registration.index.delete() all'interno del gestore contentdelete. Se l'evento è stato attivato, l'eliminazione dell'indice pertinente è già stata eseguita dal browser.

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.
});

Feedback sul design dell'API

C'è qualcosa nell'API che non funziona come previsto o che è complicato da usare? Oppure mancano elementi per implementare la tua idea?

Invia una segnalazione nel repository GitHub dell'articolo esplicativo sull'API Content Indexing o aggiungi il tuo parere a un problema esistente.

Problemi con l'implementazione?

Hai trovato un bug nell'implementazione di Chrome?

Invia un bug all'indirizzo https://new.crbug.com. Includi il maggior numero possibile di dettagli, istruzioni semplici per la riproduzione e imposta Componenti su Blink>ContentIndexing.

Hai intenzione di utilizzare l'API?

Hai intenzione di utilizzare l'API Content Indexing nella tua app web? Il tuo supporto pubblico aiuta Chrome a dare la priorità alle funzionalità e mostra ad altri fornitori di browser quanto sia importante supportarle.

Quali sono alcune implicazioni per la sicurezza e la privacy dell'indicizzazione dei contenuti?

Consulta le risposte fornite in risposta al questionario sulla sicurezza e sulla privacy del W3C. Se hai altre domande, avvia una discussione tramite il repo GitHub del progetto.

Immagine hero di Maksym Kaharlytskyi su Unsplash.