<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ PWA - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Aprenda a codificar - de graça. Tutoriais de programação em Python, JavaScript, Linux e muito mais. ]]>
        </description>
        <link>https://www.freecodecamp.org/portuguese/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ PWA - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/portuguese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 05 Jun 2026 20:06:14 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/portuguese/news/tag/pwa/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Como criar um Aplicativo Web Progressivo (PWA) do zero com HTML, CSS e JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ Aplicativos Web Progressivos (do inglês, PWA, ou Progressive Web App) são uma forma de trazer a usabilidade de um aplicativo móvel para um aplicativo web tradicional. Com eles, podemos melhorar nosso website com funcionalidades de aplicativos móveis que aumentarão a usabilidade e oferecerão uma ótima experiência de usuário.  Nesse ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-criar-um-aplicativo-web-progressivo-pwa-do-zero-com-html-css-e-javascript/</link>
                <guid isPermaLink="false">62be2c62a3520206e79cf594</guid>
                
                    <category>
                        <![CDATA[ PWA ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Deusiel da Cunha de Souza ]]>
                </dc:creator>
                <pubDate>Fri, 01 Jul 2022 17:05:54 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/Group-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/build-a-pwa-from-scratch-with-html-css-and-javascript/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to build a PWA from scratch with HTML, CSS, and JavaScript</a>
      </p><p>Aplicativos Web Progressivos (do inglês, PWA, ou <em>Progressive Web App</em>) são uma forma de trazer a usabilidade de um aplicativo móvel para um aplicativo web tradicional. Com eles, podemos melhorar nosso website com funcionalidades de aplicativos móveis que aumentarão a usabilidade e oferecerão uma ótima experiência de usuário. </p><p>Nesse artigo, criaremos um PWA do zero, com HTML, CSS e JavaScript. Aqui estão os tópicos que nós cobriremos:</p><ul><li><a href="https://www.freecodecamp.org/portuguese/news/como-criar-um-aplicativo-web-progressivo-pwa-do-zero-com-html-css-e-javascript/#o-que-um-aplicativo-web-progressivo">O que é um Aplicativo Web Progressivo?</a> </li><li><a href="https://www.freecodecamp.org/portuguese/news/como-criar-um-aplicativo-web-progressivo-pwa-do-zero-com-html-css-e-javascript/#html">HTML</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-criar-um-aplicativo-web-progressivo-pwa-do-zero-com-html-css-e-javascript/#estiliza-o">Estilização</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-criar-um-aplicativo-web-progressivo-pwa-do-zero-com-html-css-e-javascript/#exibi-o-dos-dados-com-javascript">Exibição dos dados com JavaScript</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-criar-um-aplicativo-web-progressivo-pwa-do-zero-com-html-css-e-javascript/#manifesto-do-aplicativo-web">Manifesto do Aplicativo Web</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-criar-um-aplicativo-web-progressivo-pwa-do-zero-com-html-css-e-javascript/#o-que-um-service-worker">O que é um Service Worker?</a> </li><li><a href="https://www.freecodecamp.org/portuguese/news/como-criar-um-aplicativo-web-progressivo-pwa-do-zero-com-html-css-e-javascript/#armazenamento-cache-dos-arquivos">Armazenamento (cache) dos arquivos</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-criar-um-aplicativo-web-progressivo-pwa-do-zero-com-html-css-e-javascript/#acesso-aos-arquivos">Acesso aos arquivos</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-criar-um-aplicativo-web-progressivo-pwa-do-zero-com-html-css-e-javascript/#registro-do-service-worker">Registro do Service Worker</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-criar-um-aplicativo-web-progressivo-pwa-do-zero-com-html-css-e-javascript/#conclus-es">Conclusões</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-criar-um-aplicativo-web-progressivo-pwa-do-zero-com-html-css-e-javascript/#pr-ximos-passos-textos-em-ingl-s-">Próximos passos</a></li></ul><p>Então, vamos começar com uma pergunta importante: o que é, afinal, um Aplicativo Web Progressivo (PWA)?</p><h2 id="o-que-um-aplicativo-web-progressivo"><strong>O que é um Aplicativo Web Progressivo?</strong></h2><p>Um Aplicativo Web Progressivo é um aplicativo web que entrega uma experiência semelhante a de um aplicativo móvel para os usuários usando as capacidades da web moderna. No final, é só o seu site da web normal, rodando em um navegador, com alguns melhoramentos. Aplicativos Web Progressivos têm a capacidade de:</p><ul><li>Instalar em uma página home do seu celular </li><li>Acessar o aplicativo quando você estiver desconectado da internet</li><li>Acessar a sua câmera </li><li>Receber notificações push</li><li>Manter uma sincronização em segundo plano</li></ul><p>E muito mais.</p><p>Contudo, para podermos transformar nosso aplicativo web normal em um PWA, teremos que fazer alguns pequenos ajustes, adicionando um arquivo de manifesto de aplicativo web e um service worker.</p><p>Não se preocupe com esses termos novos. Falaremos sobre eles adiante.</p><p>Primeiro, temos que construir nosso aplicativo web tradicional. Então, vamos começar com o HTML.</p><h2 id="html"><strong>HTML</strong></h2><p>O arquivo HTML é relativamente simples. Envolveremos tudo dentro de uma tag <code>main</code>.</p><ul><li>N0 arquivo <code>index.html</code></li></ul><pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
  &lt;head&gt;
    &lt;meta charset="UTF-8" /&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0" /&gt;
    &lt;meta http-equiv="X-UA-Compatible" content="ie=edge" /&gt;
    &lt;link rel="stylesheet" href="css/style.css" /&gt;
    &lt;title&gt;Dev'Coffee PWA&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;main&gt;
      &lt;nav&gt;
        &lt;h1&gt;Dev'Coffee&lt;/h1&gt;
        &lt;ul&gt;
          &lt;li&gt;Home&lt;/li&gt;
          &lt;li&gt;About&lt;/li&gt;
          &lt;li&gt;Blog&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/nav&gt;
      &lt;div class="container"&gt;&lt;/div&gt;
    &lt;/main&gt;
    &lt;script src="js/app.js"&gt;&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre><p>Vamos criar um barra de navegação com a tag <code>nav</code>. Então, uma <code>div</code> com a classe <code>.container</code>, onde ficarão todos os cartões que vamos adicionar depois com JavaScript.</p><p>Agora que terminamos essa parte, vamos estilizar nosso aplicativo com CSS.</p><h2 id="estiliza-o">Estilização</h2><p>Aqui, como de costume, começamos importando as fontes de que vamos precisar. Então, vamos redefinir alguns comportamentos (e valores) que são padrão em nosso navegador.</p><ul><li>No arquivo <code>css/style.css</code></li></ul><pre><code class="language-css">@import url("https://fonts.googleapis.com/css?family=Nunito:400,700&amp;display=swap");
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  background: #fdfdfd;
  font-family: "Nunito", sans-serif;
  font-size: 1rem;
}
main {
  max-width: 900px;
  margin: auto;
  padding: 0.5rem;
  text-align: center;
}
nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
ul {
  list-style: none;
  display: flex;
}

li {
  margin-right: 1rem;
}
h1 {
  color: #e74c3c;
  margin-bottom: 0.5rem;
}
</code></pre><p>Então, vamos limitar o tamanho do elemento <code>main</code> para largura máxima de <code>900px</code> (900 pixels) para fazer com que ele apareça bem em telas mais largas.</p><p>Para a barra de navegação, queremos que o logotipo fique à esquerda e os links à direita. Então, para a tag <code>nav</code>, depois de torná-la um "contêiner flex", usamos <code>justify-content: space-between;</code> para alinhá-las.</p><ul><li>No arquivo <code>css/style.css</code></li></ul><pre><code class="language-css">.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  grid-gap: 1rem;
  justify-content: center;
  align-items: center;
  margin: auto;
  padding: 1rem 0;
}
.card {
  display: flex;
  align-items: center;
  flex-direction: column;
  width: 15rem auto;
  height: 15rem;
  background: #fff;
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
  border-radius: 10px;
  margin: auto;
  overflow: hidden;
}
.card--avatar {
  width: 100%;
  height: 10rem;
  object-fit: cover;
}
.card--title {
  color: #222;
  font-weight: 700;
  text-transform: capitalize;
  font-size: 1.1rem;
  margin-top: 0.5rem;
}
.card--link {
  text-decoration: none;
  background: #db4938;
  color: #fff;
  padding: 0.3rem 1rem;
  border-radius: 20px;
}
</code></pre><p>Teremos alguns cartões. Por isso, o elemento com a classe <code>.container</code> será mostrado como grid. E, com a propriedade <code>grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr))</code>, podemos, agora, fazer nossos cartões ficarem responsivos, então eles podem usar pelo menos <code>15rem</code> de largura se houver espaço suficiente para isso (ou <code>1fr</code> se não houver espaço para <code>15rem</code>).</p><p>E para fazer nossos cartões ficarem ainda mais bonitos, nós duplicamos o efeito de sombra no elemento com a classe <code>.card</code> e usamos <code>object-fit: cover</code> no <code>.card--avatar</code> para evitar que a imagem estique demais.</p><p>Agora, está muito melhor. Porém, ainda não temos dados para mostrar.</p><p>Vamos consertar isso na próxima seção.</p><h2 id="exibi-o-dos-dados-com-javascript">Exibição dos dados com JavaScript</h2><p>Note que usei imagens grandes, que demoram algum tempo para carregar. Isso mostrará a você, da melhor forma, o poder dos service workers.</p><p>Como disse antes, a classe <code>.container</code> conterá nossos cartões. Portanto, precisamos selecioná-la com nosso código JavaScript.</p><ul><li>No arquivo <code>js/app.js</code></li></ul><pre><code class="language-javascript">const container = document.querySelector(".container")
const coffees = [
  { name: "Perspiciatis", image: "images/coffee1.jpg" },
  { name: "Voluptatem", image: "images/coffee2.jpg" },
  { name: "Explicabo", image: "images/coffee3.jpg" },
  { name: "Rchitecto", image: "images/coffee4.jpg" },
  { name: " Beatae", image: "images/coffee5.jpg" },
  { name: " Vitae", image: "images/coffee6.jpg" },
  { name: "Inventore", image: "images/coffee7.jpg" },
  { name: "Veritatis", image: "images/coffee8.jpg" },
  { name: "Accusantium", image: "images/coffee9.jpg" },
]
</code></pre><p>Então, criamos um array de cartões com os nomes e imagens.</p><ul><li>No arquivo <code>js/app.js</code></li></ul><pre><code class="language-javascript">const showCoffees = () =&gt; {
  let output = ""
  coffees.forEach(
    ({ name, image }) =&gt;
      (output += `
              &lt;div class="card"&gt;
                &lt;img class="card--avatar" src=${image} /&gt;
                &lt;h1 class="card--title"&gt;${name}&lt;/h1&gt;
                &lt;a class="card--link" href="#"&gt;Taste&lt;/a&gt;
              &lt;/div&gt;
              `)
  )
  container.innerHTML = output
}

document.addEventListener("DOMContentLoaded", showCoffees)
</code></pre><p>Com o código acima, podemos fazer um loop no array e renderizar os elementos no nosso arquivo HTML. E, para fazer tudo funcionar, esperamos até que o conteúdo do DOM (Modelo de Objeto de Documentos) termine de carregar para que possamos executar o método <code>showCoffees</code>.</p><p>Já fizemos muito, mas, por agora, temos somente um aplicativo web tradicional. Então, vamos mudar isso na próxima seção, introduzindo algumas funcionalidades de Aplicativo Web Progressivo.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/source.gif" class="kg-image" alt="source" width="500" height="281" loading="lazy"></figure><h2 id="manifesto-do-aplicativo-web"><strong>Manifesto do Aplicativo Web </strong></h2><p>O manifesto do aplicativo web é um simples arquivo em formato JSON, que informa ao navegador sobre o seu aplicativo web. Esse manifesto informa como o aplicativo deve se comportar quando for instalado no dispositivo móvel do usuário ou no seu desktop. E, para mostrar a opção de adicionar à tela inicial, é obrigatório ter o manifesto.</p><p>Agora que já sabemos o que é um manifesto, vamos criar um novo arquivo chamado <code>manifest.json</code> (o nome precisa ser esse) na pasta raiz. Então, vamos adicionar o bloco de código abaixo.</p><ul><li>No arquivo <code>manifest.json</code></li></ul><pre><code class="language-javascript">{
  "name": "Dev'Coffee",
  "short_name": "DevCoffee",
  "start_url": "index.html",
  "display": "standalone",
  "background_color": "#fdfdfd",
  "theme_color": "#db4938",
  "orientation": "portrait-primary",
  "icons": [
    {
      "src": "/images/icons/icon-72x72.png",
      "type": "image/png", "sizes": "72x72"
    },
    {
      "src": "/images/icons/icon-96x96.png",
      "type": "image/png", "sizes": "96x96"
    },
    {
      "src": "/images/icons/icon-128x128.png",
      "type": "image/png","sizes": "128x128"
    },
    {
      "src": "/images/icons/icon-144x144.png",
      "type": "image/png", "sizes": "144x144"
    },
    {
      "src": "/images/icons/icon-152x152.png",
      "type": "image/png", "sizes": "152x152"
    },
    {
      "src": "/images/icons/icon-192x192.png",
      "type": "image/png", "sizes": "192x192"
    },
    {
      "src": "/images/icons/icon-384x384.png",
      "type": "image/png", "sizes": "384x384"
    },
    {
      "src": "/images/icons/icon-512x512.png",
      "type": "image/png", "sizes": "512x512"
    }
  ]
}
</code></pre><p>No final, é só um arquivo JSON com algumas propriedades obrigatórias e outras opcionais.</p><p>name: Quando o navegador iniciar a tela de boas-vindas, esse será o nome mostrado na tela de boas-vindas</p><p>short_name: Será o nome que aparecerá abaixo do atalho para seu aplicativo na tela inicial</p><p>start_url: Será a página mostrada ao usuário quando o seu aplicativo for aberto.</p><p>display: Informará ao seu navegador como mostrar o aplicativo. Existem diversas formas de mostrar, como <code>minimal-ui</code>, <code>fullscreen</code>, <code>browser</code>, etc. Aqui, nós usaremos o modo <code>standalone</code> para esconder qualquer coisa relacionada com o navegador.</p><p>background_color: Quando o navegador iniciar a tela de boas-vindas, essa será a cor de fundo da tela.</p><p>theme_color: Essa será a cor da barra de status quando o app for aberto.</p><p>orientation: Informa ao navegador em qual orientação (horizontal ou vertical) mostrar o app.</p><p>icons: Quando o navegador carregar a página de boas-vindas, esse será o ícone mostrado na tela. Aqui, eu usei todos os tamanhos para que o app se ajuste a qualquer dispositivo, mas você pode usar um ou dois. Depende da sua escolha.</p><p>Agora que nós temos um manifesto de aplicativo web, vamos adicioná-lo ao nosso arquivo HTML.</p><ul><li>No arquivo <code>index.html</code> (na tag <em>head</em>)</li></ul><pre><code class="language-html">&lt;link rel="manifest" href="manifest.json" /&gt;
&lt;!-- ios support --&gt;
&lt;link rel="apple-touch-icon" href="images/icons/icon-72x72.png" /&gt;
&lt;link rel="apple-touch-icon" href="images/icons/icon-96x96.png" /&gt;
&lt;link rel="apple-touch-icon" href="images/icons/icon-128x128.png" /&gt;
&lt;link rel="apple-touch-icon" href="images/icons/icon-144x144.png" /&gt;
&lt;link rel="apple-touch-icon" href="images/icons/icon-152x152.png" /&gt;
&lt;link rel="apple-touch-icon" href="images/icons/icon-192x192.png" /&gt;
&lt;link rel="apple-touch-icon" href="images/icons/icon-384x384.png" /&gt;
&lt;link rel="apple-touch-icon" href="images/icons/icon-512x512.png" /&gt;
&lt;meta name="apple-mobile-web-app-status-bar" content="#db4938" /&gt;
&lt;meta name="theme-color" content="#db4938" /&gt;
</code></pre><p>Como você pode ver, nosso arquivo <code>manifest.json</code> foi importado na tag <em>head</em>. Também importamos alguns outros links para podermos oferecer suporte para sistemas iOS na hora de mostrar ícones e colorir nossa barra de status com nosso tema de cores.</p><p>Com isso, agora podemos mergulhar mais fundo na parte final e introduzir o conceito de service worker.</p><h2 id="o-que-um-service-worker"><strong>O que é um<strong> Service Worker?</strong></strong></h2><p>Note que Aplicativos Web Progressivos (PWAs) funcionarão apenas em https, porque o service worker pode acessar as requisições e lidar com elas.</p><p>Um service worker é um script que seu navegador executa em segundo plano em uma thread separada. Isso significa que ele é executado em um lugar completamente diferente da sua página web. Essa é a razão pela qual ele não pode manipular os elementos do DOM.</p><p>Contudo, ele é muito poderoso. O service worker pode interceptar e lidar com requisições de rede, gerenciar o cache para possibilitar o uso off-line ou enviar notificações push para seus usuários.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/source--1-.gif" class="kg-image" alt="source--1-" width="470" height="376" loading="lazy"></figure><p>Então, vamos criar nosso primeiro service worker na pasta raiz e dar a ele o nome de <code>serviceWorker.js</code> (você pode usar o nome que quiser). Porém, você deve colocá-lo na pasta raiz para não limitar o escopo a apenas uma pasta.</p><h3 id="armazenamento-cache-dos-arquivos"><strong>Armazenamento (cache) dos arquivos </strong></h3><ul><li>No arquivo <code>serviceWorker.js</code></li></ul><pre><code class="language-javascript">const staticDevCoffee = "dev-coffee-site-v1"
const assets = [
  "/",
  "/index.html",
  "/css/style.css",
  "/js/app.js",
  "/images/coffee1.jpg",
  "/images/coffee2.jpg",
  "/images/coffee3.jpg",
  "/images/coffee4.jpg",
  "/images/coffee5.jpg",
  "/images/coffee6.jpg",
  "/images/coffee7.jpg",
  "/images/coffee8.jpg",
  "/images/coffee9.jpg",
]

self.addEventListener("install", installEvent =&gt; {
  installEvent.waitUntil(
    caches.open(staticDevCoffee).then(cache =&gt; {
      cache.addAll(assets)
    })
  )
})
</code></pre><p>Esse código parece intimidador no começo, mas é só JavaScript (então, não se preocupe).</p><p>Declaramos o nome do nosso cache <code>staticDevCoffee</code> e os arquivos para salvar no cache. Após fazermos isso, precisamos adicionar um listener ao <code>self</code>.</p><p><code>self</code> é o service worker. Ele nos permite "ouvir" o ciclo de vida dos eventos e fazer alguma coisa quando esses eventos de fato acontecem.</p><p>O service worker tem alguns ciclos de vida e um deles é o evento <code>install</code>. Ele é executado quando um service worker é instalado. Ele executa tão logo um worker execute e somente é executado uma vez por service worker.</p><p>Quando o evento <em>install</em> é acionado, executamos uma função de retorno (callback), que nos dará acesso ao objeto <code>event</code>.</p><p>Armazenar alguma coisa no navegador pode levar algum tempo para terminar, porque é assíncrono.</p><p>Então, para lidar com isso, precisamos usar <code>waitUntil()</code> que, como você pode imaginar, vai esperar o carregamento para, então, finalizar.</p><p>Uma vez que a API do cache está pronta, podemos executar o método <code>open()</code> e criar nosso cache passando o nome do nosso cache como um argumento, assim: <code>caches.open(staticDevCoffee)</code></p><p>Então, essa função nos retornará uma <em>Promise</em>, que nos ajuda a armazenar nossos arquivos no cache com <code>cache.addAll(assets)</code>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/cached-images.png" class="kg-image" alt="cached-images" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/07/cached-images.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/07/cached-images.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/07/cached-images.png 1278w" sizes="(min-width: 720px) 720px" width="1278" height="655" loading="lazy"></figure><p>Espero que você ainda esteja comigo.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/source--2-.gif" class="kg-image" alt="source--2-" width="150" height="123" loading="lazy"></figure><p>Agora, armazenamos nossos arquivos no navegador com sucesso. E, na próxima vez em que carregarmos a página, o service worker lidará com as requisições e acessará o cache se estivermos off-line.</p><p>Então, vamos acessar nosso cache.</p><h3 id="acesso-aos-arquivos"><strong>Acesso aos arquivos</strong></h3><ul><li>No arquivo <code>serviceWorker.js</code></li></ul><pre><code class="language-javascript">self.addEventListener("fetch", fetchEvent =&gt; {
  fetchEvent.respondWith(
    caches.match(fetchEvent.request).then(res =&gt; {
      return res || fetch(fetchEvent.request)
    })
  )
})
</code></pre><p>Aqui, usamos o evento <code>fetch</code> para obter nossos dados. A função de retorno (callback) nos dá acesso ao <code>fetchEvent</code>. Então, acoplamos <code>respondWith()</code> para modificar a resposta padrão do navegador. Em vez disso (da resposta padrão), a função retorna uma <em>promise</em>, já que a ação de acessar os arquivos pode demorar algum tempo para terminar.</p><p>Quando o cache estiver pronto, podemos aplicar <code>caches.match(fetchEvent.request)</code>. Isso verificará se alguma coisa no cache corresponde a <code>fetchEvent.request</code>. Para que você saiba, <code>fetchEvent.request</code> é apenas um array de arquivos.</p><p>Então, a função retorna uma <em>promise</em>. Finalmente, podemos retornar os resultados, se eles existirem, ou fazer o fetch inicial caso não existam resultados a exibir.</p><p>Agora, nossos arquivos podem ser armazenados e acessados pelo service worker, o que melhora o tempo de carregamento das nossas imagens um pouco.</p><p>E o mais importante: isso faz com que o nosso app fique disponível off-line.</p><p>O service worker, porém, não consegue fazer todo o trabalho sozinho. Precisamos registrá-lo em nosso projeto.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/source--3-.gif" class="kg-image" alt="source--3-" width="320" height="180" loading="lazy"></figure><h2 id="registro-do-service-worker"><strong>Registro do<strong> Service Worker</strong></strong></h2><ul><li>No arquivo <code>js/app.js</code></li></ul><pre><code class="language-javascript">if ("serviceWorker" in navigator) {
  window.addEventListener("load", function() {
    navigator.serviceWorker
      .register("/serviceWorker.js")
      .then(res =&gt; console.log("service worker registered"))
      .catch(err =&gt; console.log("service worker not registered", err))
  })
}
</code></pre><p>Aqui, verificamos se o service worker é suportado pelo nosso navegador (ele não é suportado por todos os navegadores).</p><p>Então, "ouvimos" o evento de carregamento da página para registrar nosso service worker, passando para ele o nome do arquivo <code>serviceWorker.js</code> para <code>navigator.serviceWorker.register()</code> como parâmetro para registrá-lo.</p><p>Com esse ajuste, agora transformamos nosso aplicativo web normal em um PWA.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/source--4-.gif" class="kg-image" alt="source--4-" width="480" height="266" loading="lazy"></figure><h2 id="conclus-es"><strong>Conclusões</strong></h2><p>Através deste artigo, vimos que os PWAs podem ser maravilhosos. Adicionando um manifesto de aplicativo web e um service worker, realmente melhoramos a experiência de usuário do nosso aplicativo web tradicional. Isso ocorre porque os PWAs são rápidos, seguros, confiáveis e, o mais importante de tudo, eles permitem o uso off-line. </p><p>Muitos frameworks atuais já vêm com um service worker configurado para nós. Saber como implementá-los com JavaScript puro, no entanto, pode ajudá-lo a entender os PWAs.</p><p>Você pode ir mais além com os service workers, como, por exemplo: armazenar arquivos dinamicamente, limitar o tamanho do seu armazenamento e assim por diante.</p><p>Obrigado por ler esse artigo.</p><p>Você pode ver como o aplicativo ficou <a href="https://devcoffee-pwa.netlify.com/">aqui </a>e o código fonte <a href="https://github.com/ibrahima92/pwa-with-vanilla-js">aqui</a>.</p><p>Leia mais artigos do autor no <a href="https://www.ibrahima-ndaw.com/blog/how-to-build-pwa-with-javascript/">blog do autor</a>.</p><h2 id="pr-ximos-passos-textos-em-ingl-s-"><strong>Próximos passos (textos em inglês)</strong></h2><p><a href="https://developers.google.com/web/fundamentals/web-app-manifest">Web Manifest Documentation</a> (documentação do manifesto da web)</p><p><a href="https://developers.google.com/web/fundamentals/primers/service-workers">Service Worker Documentation</a> (documentação do service worker)</p><p><a href="https://app-manifest.firebaseapp.com/">Web Manifest Generator</a> (gerador do manifesto da web)</p><p><a href="https://caniuse.com/#search=service%20worker">Browser Support</a> (suporte aos navegadores)</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
