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

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

Che cos'è l'API Content Index?

Utilizzare un'app web progressiva significa avere accesso a informazioni importanti per gli utenti, 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 forniscono i componenti di base per l'archiviazione e la gestione dei dati quando le persone interagiscono direttamente con una PWA. Ma la creazione di una PWA offline di alta qualità è solo parte di questo. Se le persone non si rendono conto che i contenuti di un'app web sono disponibili mentre sono offline, non approfittano appieno del lavoro che dedichi all'implementazione di tale funzionalità.

Questo è un problema di scoperta: in che modo la PWA può informare gli utenti dei suoi contenuti offline in modo che possano scoprire e visualizzare i contenuti disponibili? L'API di indicizzazione dei contenuti è una soluzione a questo problema. La parte rivolta agli sviluppatori di questa soluzione è un'estensione per i service worker, che consente loro di aggiungere URL e metadati di pagine offline a un indice locale gestito dal browser. Questo miglioramento è disponibile in Chrome 84 e versioni successive.

Una volta che l'indice viene completato con i contenuti della PWA e di eventuali altre PWA installate, verrà visualizzato dal browser come mostrato di seguito.

Uno screenshot della voce di menu Download nella pagina Nuova scheda di Chrome.
Innanzitutto, seleziona la voce 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 visualizzati nella sezione Articoli per te.

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

L'API di indicizzazione dei contenuti non è un modo alternativo per memorizzare i contenuti nella cache. È un modo per fornire metadati sulle pagine già memorizzate nella cache dal personale del servizio, in modo che il browser possa mostrare tali pagine quando è probabile che gli utenti vogliano visualizzarle. L'API di indicizzazione dei contenuti facilita la rilevabilità delle pagine memorizzate nella cache.

Guarda come funziona

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

  1. Assicurati di utilizzare un browser e una piattaforma supportati. Attualmente questa funzionalità è limitata a Chrome 84 o versioni successive su Android. Visita il sito about://version per verificare quale versione di Chrome è in uso.
  2. Visita il sito https://contentindex.dev
  3. Fai clic sul pulsante + accanto a uno o più elementi dell'elenco.
  4. (Facoltativo) Disattiva la connessione alla rete dati e Wi-Fi del dispositivo oppure attiva la modalità aereo per simulare la disconnessione del browser.
  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 Sccrapbook, illustra l'utilizzo dell'API Content Index con l'API Web Share Target. Il codice mostra una tecnica per mantenere sincronizzata l'API Content Index con gli elementi archiviati da un'app web utilizzando l'API Cache Storage.

Utilizzo dell'API

Per utilizzare l'API, l'app deve avere un service worker e URL raggiungibili offline. Se la tua app web al momento non dispone di un service worker, le librerie di Workbox possono semplificare la creazione di uno.

Quale tipo di URL può essere indicizzato come offline?

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

Un pattern consigliato consiste nel creare una pagina HTML "visualizzatore" in grado di accettare l'URL multimediale sottostante come parametro di query e quindi di visualizzare i contenuti del file, potenzialmente con controlli o contenuti aggiuntivi nella pagina.

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

Panoramica

L'API di indicizzazione dei contenuti supporta tre operazioni: aggiunta, elenco e rimozione dei metadati. Questi metodi sono stati esposti da una nuova proprietà, index, che è stata aggiunta all'interfaccia ServiceWorkerRegistration.

Il primo passaggio per indicizzare i contenuti è ottenere un riferimento all'attuale ServiceWorkerRegistration. L'uso di navigator.serviceWorker.ready è il modo più diretto:

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 Index da un service worker, invece che dall'interno di una pagina web, puoi fare riferimento all'ServiceWorkerRegistration direttamente tramite registration. Sarà già definito nell'ambito del ServiceWorkerGlobalScope.

Aggiunta all'indice in corso...

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

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 influisce solo sull'indice dei contenuti, non sulla cache.

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

Quando chiami add(), Chrome richiederà l'URL di ogni icona per assicurarsi che contenga una copia dell'icona da utilizzare per la visualizzazione di un elenco di contenuti indicizzati.

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

  • Se chiami add() all'interno del tuo service worker (forse all'interno di un altro gestore di eventi), la richiesta non attiverà il gestore fetch del service worker. Le icone verranno recuperate direttamente, senza l'intervento del service worker. Tieni presente questo aspetto se le icone si basano sul gestore fetch, ad esempio perché esistono solo nella cache locale e non sulla rete. Se sì, 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 i 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 elimina nulla dalla cache.

Gestire un evento di eliminazione di un utente

Quando il browser visualizza i contenuti indicizzati, potrebbe includere la propria interfaccia utente con una voce di menu Elimina, dando agli utenti la possibilità di indicare che hanno finito di visualizzare i contenuti indicizzati in precedenza. Ecco come appare l'interfaccia di eliminazione in Chrome 80:

La voce di menu Elimina.

Quando qualcuno seleziona quella voce di menu, il service worker della tua app web riceverà un evento contentdelete. Sebbene la gestione di questo evento sia facoltativa, offre al service worker la possibilità di "ripulire" i contenuti, ad esempio i file multimediali memorizzati nella cache locale, di cui qualcuno ha indicato di aver finito.

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 sulla progettazione dell'API

C'è qualcosa nell'API che non funziona o non funziona come previsto? O mancano alcuni elementi di cui hai bisogno per realizzare la tua idea?

Segnala un problema nel repository GitHub esplicativo dell'API Content Index oppure aggiungi le tue opinioni su un problema esistente.

Problemi con l'implementazione?

Hai trovato un bug nell'implementazione di Chrome?

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

Prevedi di utilizzare l'API?

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

Quali sono alcune implicazioni relative a sicurezza e privacy dell'indicizzazione dei contenuti?

Consulta le risposte fornite in risposta al questionario sulla sicurezza e la privacy del W3C. In caso di ulteriori domande, avvia una discussione tramite il repository GitHub del progetto.

Immagine hero di Maksym Kaharlytskyi su Unsplash.