Frontends com Vibecoding · Capítulo 29 de 33 · 20 min
Construir um aplicativo instalável e resiliente
O site vira aplicativo instalável, com cache por tipo de arquivo, banco local para editar sem rede e comportamento previsível quando a conexão cai.
Este capítulo faz parte do curso gratuito Frontends com Vibecoding.
Instalar o site como aplicativo e fazer o site funcionar sem rede são duas conquistas separadas, e quase todo pedido confunde as duas. O manifesto, que é o cartão de identidade do site, diz o nome, o ícone e o modo como a tela abre. Ele coloca o atalho na tela do celular e para por aí.
Quem decide isso é quem conversa com o agente, ou seja, o assistente de código que executa o pedido escrito. A ordem em que as peças entram, o que fica guardado no aparelho e os ajustes contra o botão cortado saem todos dessa primeira escolha.
PWA quer dizer aplicativo web progressivo: o mesmo site que abre no navegador, com recursos que o aproximam de um aplicativo de loja. Ele exige publicação em endereço seguro, o HTTPS. Um arquivo aberto direto do disco não conta como publicação.
O service worker, que é um porteiro instalado entre a tela e a rede, guarda cópias das páginas e decide o que entregar quando o sinal cai. Ele funciona numa aba comum, sem instalação. Teste visitando conectado e reabrindo sem rede: quem chega pela primeira vez já sem sinal não vê nada, porque nada foi guardado ainda.
Ir para a loja de aplicativos só compensa com um de dois gatilhos. Ou o site precisa de câmera, sensores e biometria, ou a sua venda depende da vitrine da loja. Fora disso, instalar pela web mantém um código só para web, Android e iPhone, e publica correção em segundos, sem esperar a aprovação de terceiro.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
A instalação não acontece do mesmo jeito nos dois sistemas, e isso muda o texto da sua tela. No Chrome para Android o próprio navegador oferece a instalação, e o site pode montar o convite dentro da página.
No iPhone e no iPad não existe convite automático. A pessoa precisa abrir o menu de compartilhamento e tocar em Adicionar à Tela de Início, então o site precisa ensinar isso por escrito.
A notificação, que é a mensagem que aparece na tela do celular sem o site estar aberto, segue a mesma regra. No iPhone e no iPad ela só chega depois que a pessoa adicionou o aplicativo à Tela de Início. Quem conta com aviso de pedido pronto precisa pedir essa instalação primeiro.
Cache é a cópia que o aparelho guarda para mostrar sem pedir de novo ao servidor, e a escolha de cache muda por tipo de arquivo. O Workbox, um pacote pronto que monta o service worker para você, traz as três estratégias já escritas, e está em 54% dos sites feitos para celular.
Em Cache First, o aparelho entrega primeiro a cópia guardada. Serve fonte, ícone e imagem que quase nunca mudam: a tela aparece na hora, com o risco de mostrar versão antiga. Network First pergunta ao servidor antes. Serve preço, login e pagamento, porque ali o dado velho custa caro.
A terceira, Stale-While-Revalidate, entrega a cópia guardada e busca a versão nova por trás, para a próxima visita. Serve a foto de perfil e o texto institucional, que aguentam estar um dia atrasados.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
O erro mais comum do service worker escrito por agente é aplicar uma estratégia só ao site inteiro. O segundo é guardar o arquivo pelo endereço: você publica a correção, o endereço continua igual, e o cliente segue vendo a tela de ontem. A saída é identificar o arquivo pelo conteúdo, porque conteúdo novo gera identificador novo.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
Instalado, o site abre dentro da moldura do celular, e três ajustes de CSS separam um aplicativo de um site encolhido. A altura medida em vh ignora a barra de endereço e faz o bloco de abertura estourar; a unidade dvh acompanha a barra conforme ela some.
O recorte da câmera e a barra de gestos pedem dois passos na ordem. Primeiro escreva viewport-fit=cover na linha de configuração de tela; depois some o recuo que o sistema informa a um espaçamento mínimo seu no botão fixo. Sem o primeiro passo, o segundo devolve zero.
Falta o gesto de arrastar. A regra touch-action: pan-y deixa o carrossel deslizar de lado sem brigar com a rolagem, e overscroll-behavior: contain impede que a lista puxe a tela de trás. O botão cortado aparece no celular do cliente, nunca no seu, então teste num aparelho de verdade.
/* 1. altura que acompanha a barra do navegador */
.abertura { min-height: 100dvh; }
/* 2. área segura: exige viewport-fit=cover na meta de viewport
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> */
.barra-acao {
padding-bottom: max(16px, env(safe-area-inset-bottom));
}
/* 3. gestos: o carrossel arrasta de lado e a lista não vaza para a página */
.carrossel { touch-action: pan-y; }
.janela-lista { overscroll-behavior: contain; }Cache resolve ler sem rede; gravar sem rede é outro problema, e a resposta chama-se local-first. O dado nasce e mora no aparelho, e sobe para o servidor quando o sinal volta, como um caderno que se copia sozinho ao chegar na loja.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
O motor dessa ideia é o CRDT, uma estrutura que funde a edição de duas pessoas sem perguntar qual delas venceu. O Yjs é o mais usado e move editores conhecidos, então é a escolha para quem edita texto a quatro mãos.
Já o Automerge guarda o histórico de quem mudou o quê, e vale quando a auditoria pesa mais que o tempo real.
Quando o aplicativo tem tabelas e regra de negócio, ElectricSQL, Zero e TinyBase colocam um banco de dados dentro do aparelho e cuidam da sincronização. Já o relatório que abre sem rede pede o banco dentro do próprio navegador, e o SQLite Wasm é o padrão leve.
Editar sem rede e guardar dados no navegador: a ferramenta pelo critério
| Ferramenta | Escolha quando | Armadilha |
|---|---|---|
| Workbox | o site precisa abrir sem rede; service worker pronto com as três estratégias, em 54% dos sites mobile | uma estratégia só para o site inteiro |
| Yjs | edição em tempo real de texto ou quadro; CRDT com o maior ecossistema, cerca de 920 mil downloads semanais, motor de Notion, TipTap e BlockNote | tratar como banco: ele funde edições e não consulta tabela |
| Automerge | a auditoria de quem editou importa mais que o tempo real; histórico estilo Git | documento grande carrega o histórico inteiro |
| ElectricSQL, Zero, TinyBase | app com tabelas e regra de conflito; SQLite no aparelho com sincronização, Zero com mutators TypeScript, TinyBase como pacote único MIT | sincronizar tudo sem filtro de permissão por usuário |
| TanStack DB 0.6 | protótipo; segue em beta, rumo à v1 com SSR | levar a versão beta para produção |
| SQLite Wasm 3.53 | relatório offline com dados locais leves; cerca de 400 KB gzip | guardar só em memória e perder tudo ao fechar a aba |
| PGlite 0.5.8 | extensões e tipos do Postgres justificam o peso; Postgres 16 real em cerca de 3,3 MB | pagar 3,3 MB por uma tabela de contatos |
| DuckDB-Wasm | somar milhões de linhas dentro do relatório offline; análise colunar | contar com paridade com o núcleo nativo (base 1.5.4, Arrow 17) |
Cache resolve leitura sem rede; edição sem rede pede local-first, e relatório offline seguro pede o banco dentro do navegador.
O critério que separa os dois é simples: cache resolve ver, local-first resolve gravar. Numa distribuidora de bebidas, o vendedor que entra em bairro sem sinal consegue mostrar o catálogo de ontem com cache, mas só registra o pedido com local-first. A última caixa vendida duas vezes continua sendo decisão de regra de negócio no servidor.
Antes de pedir o service worker ao agente, escreva qual estratégia vale para cada tipo de arquivo. Cópia primeiro para fonte e ícone, servidor primeiro para dados e pagamento, cópia com atualização por trás para o resto.
Depois publique uma correção pequena e recarregue a página no celular. Se o texto antigo continuar na tela, o cache está preso ao endereço, e não ao conteúdo, e é esse o ajuste a pedir em seguida.
Guia prático: o que uma tela de autoatendimento ensina ao app instalável
Totem de pedido em restaurante é o caso extremo de tela de toque: a pessoa está em pé, com pressa, sem teclado e sem paciência para errar. O template de totem estudado em 07/10/2026 cabe em duas telas e 205 linhas de código, e mostra os acertos e os tropeços que valem para qualquer app instalável.
Os acertos: a tela inicial inteira é o alvo de toque; a barra de ação ocupa de 140 a 160 px de altura; o botão de pagar fica fixo embaixo, perto do polegar, com cerca de 60 px de altura; o cartão encolhe a 95% no instante do toque, o que confirma o gesto sem esperar a rede; a altura usa a unidade que acompanha a barra do navegador; e o fluxo é curto: tocar, escolher categoria, escolher item, pagar.
Os tropeços: o código bloqueia o zoom, o que um totem pode fazer e um site público não deve, porque tira o recurso de quem enxerga pouco. Os rótulos das categorias têm 10 px. A tela inicial é um bloco clicável sem botão, que o teclado e o leitor de tela não alcançam. Os efeitos de passar o mouse não existem no toque. As imagens dos produtos vêm de dois serviços externos, então sem rede a vitrine some, e não há aviso de estado offline. O template ainda usa nome e logo de uma rede real de lanchonetes, o que não se publica com a marca de outro.
A WCAG 2.2 pede alvo de pelo menos 24 por 24 px; para dedo em pé, mire perto do dobro.
Levar o desenho de totem para o seu app instalável
Cinco passos para revisar uma tela de toque antes de publicar o app.
Passo 1: Conte os toques do fluxo principal
Escreva o caminho do pedido, do agendamento ou da compra, do primeiro toque à confirmação. Cada etapa que não decide nada sai ou vira padrão já marcado.
Deu certo quando: O fluxo principal cabe em até cinco toques, contados na tela real.
Erro comum: Pedir cadastro antes de mostrar o produto, como se a pessoa tivesse tempo de sobra.
Passo 2: Meça os alvos com o dedo, não com o mouse
No celular, toque cada botão com o polegar em pé. No inspetor, confira a caixa de cada alvo: nenhum abaixo de 24 px, e os principais perto de 48 px, com espaço entre vizinhos.
Deu certo quando: Nenhum toque errado no fluxo principal em três tentativas seguidas.
Erro comum: Confiar no rótulo de 10 px porque "o ícone é grande".
Passo 3: Responda ao toque antes da rede
O botão muda de estado no instante do toque: encolhe, escurece ou mostra o carregamento. Efeito de passar o mouse sai ou ganha equivalente no toque e no foco.
Deu certo quando: Todo toque tem resposta visual em menos de 100 ms, mesmo com a rede lenta.
Erro comum: Deixar o botão parado até o servidor responder e receber o segundo toque, que duplica o pedido.
Passo 4: Desenhe o estado sem rede
Imagens do catálogo ficam no próprio app, no cache. Sem conexão, a tela avisa em texto, mostra a hora da última atualização e desliga só o que depende da rede, como preço e pagamento.
Deu certo quando: Com o modo avião ligado, o catálogo aparece e o aviso diz o que está indisponível.
Erro comum: Puxar imagem de serviço externo e mostrar caixas vazias ao primeiro túnel.
Passo 5: Libere o zoom e o teclado no app público
Totem dedicado pode bloquear zoom; app que qualquer pessoa instala, não. Toda área clicável vira botão de verdade, alcançável por Tab e com nome para o leitor de tela.
Deu certo quando: O zoom de dois dedos funciona e o fluxo inteiro anda só pelo teclado.
Erro comum: Copiar a meta de viewport do template de totem para o app público.
No fim você tem: Um app instalável com fluxo curto, alvos do tamanho do dedo, resposta imediata ao toque e um estado offline que diz o que ainda funciona.
Sócio de uma rede de três açaiterias em Fortaleza que lança o pedido pelo celular para retirar no balcão
Alimentação, pedido antecipado
Dor
A primeira versão do app tinha seis etapas, botões pequenos de adicionais e fotos que sumiam quando o cliente estava no estacionamento sem sinal.
Solução
Ele pediu ao agente o fluxo de totem: tocar, escolher tamanho, adicionais em botões grandes, pagar. As fotos foram para o cache do app, e o aviso offline passou a dizer que o cardápio estava disponível e o pagamento voltaria com a conexão.
Resultado
O pedido ficou em quatro toques, e o cardápio continuou visível sem sinal, com o pagamento claramente em espera.
Cenário construído para fins didáticos. Números não correspondem a cliente específico.
Guia prático: botão de instalar nativo, rotas que dispensam o service worker e o manifesto deste portal
O convite para instalar deixou de depender de script próprio: o Chrome testa o elemento <install> e a função navigator.install(), e o Safari 27 passou a aceitar rotas estáticas no service worker. O guia mostra o que cada recurso faz, como o manifesto e o service worker deste portal resolvem atalhos, retomada e páginas sem rede, e o pedido que leva isso a um app de campanha.
Funções, casos de uso e aplicações
Funções
Recursos de app instalável em teste ou recém-chegados
| Função ou recurso | O que faz | Quando usar | Desde |
|---|---|---|---|
| Elemento <install> | Botão de instalação desenhado pelo próprio navegador. O conteúdo escrito dentro dele aparece onde o elemento não existe. Exige id no manifesto | Página de campanha que quer o convite visível sem montar a lógica do beforeinstallprompt | 12/05/2026 (teste de origem, Chrome e Edge 148 a 153) |
| <install installurl> e manifestid | Instala um app de outra origem a partir da sua página; manifestid informa o id calculado quando o manifesto do outro app não declara um | Portal de um grupo que oferece os apps de cada marca numa página só | 12/05/2026 (teste de origem) |
| navigator.install() | A versão em JavaScript do convite: interface toda sua, mas exige um gesto da pessoa, como um toque | Quando o botão precisa seguir o desenho da marca | Chrome 156 beta (resumo de 02/10/2026) |
| Rotas estáticas do service worker (InstallEvent.addRoutes) | Regras declaradas na instalação mandam certos pedidos direto para a rede ou para um cache, sem acordar o service worker | Rotas que o service worker só deixaria passar, como API autenticada e envio de formulário | Chrome e Edge 123; Safari 27 em setembro de 2026 |
| sizes="auto" em imagem com carregamento adiado | O navegador calcula o tamanho da imagem pela largura do layout e escolhe o arquivo certo do srcset | Vitrine de produtos e lista de turmas dentro do app | Baseline recém-disponível com o Safari 27 (setembro de 2026) |
Teste de origem é o período em que um recurso experimental funciona em produção só para sites inscritos, com prazo de fim. Todo uso precisa de reserva para quem não tem o recurso.
Fonte: Chrome for Developers, blog do elemento install (12/05/2026); web.dev, New to the web platform in September (02/10/2026); MDN, InstallEvent.addRoutes
Casos de uso
Coordenador pedagógico de um cursinho pré-vestibular em Salvador
Educação, app de simulados
Dor
Os alunos não achavam o ícone de instalar na barra do navegador, e no iPhone ninguém sabia o caminho pelo menu de compartilhar.
Solução
A página do app ganhou o elemento <install> com o texto de reserva por dentro: no Chrome aparece o botão do navegador; nos demais, o passo a passo de Adicionar à Tela de Início. O manifesto recebeu id e atalhos para Simulado do dia e Minhas notas.
Resultado
O que observar: em quatro semanas, quantas visitas chegam com utm_source=pwa no endereço de início e quantas pelos atalhos.
Cenário construído para fins didáticos. Números não correspondem a cliente específico.
Gerente de produto digital de uma rede de academias em Goiânia
Marketing digital, app de agendamento de aula experimental
Dor
O service worker interceptava até o envio do formulário de agendamento, e no celular fraco o primeiro toque demorava a responder enquanto ele acordava.
Solução
As rotas de envio de formulário e de API de login passaram para regras estáticas com saída direta para a rede, e o service worker ficou só com páginas e imagens da vitrine.
Resultado
O que observar: em 28 dias, o INP (tempo entre o toque e a próxima pintura da tela) dos aparelhos reais no botão de agendar, separado por navegador.
Cenário construído para fins didáticos. Números não correspondem a cliente específico.
Na prática
O manifesto do portal, em public/manifest.json, já tem o que o elemento <install> exige: "id": "/". O endereço de início leva utm_source=pwa, então toda abertura pelo ícone aparece separada na medição. Três atalhos levam a Continuar de onde parei, Revisão do dia e Liga da semana, cada um com a própria campanha no endereço. O share_target faz o portal aparecer na lista de compartilhar do celular e manda o texto para a busca.
O service worker, em public/sw.js, conta a lição mais cara. Na versão 3, o HTML de /educacao vinha do cache enquanto o resto vinha da rede, e depois de cada publicação a página antiga pedia arquivos que já não existiam. A regra atual: toda página HTML é rede primeiro, /_next/static com rede fica com o navegador e as rotas sensíveis passam direto.
{
"id": "/",
"short_name": "Educação GEO",
"start_url": "/educacao?utm_source=pwa",
"scope": "/",
"display": "standalone",
"launch_handler": { "client_mode": ["navigate-existing", "auto"] },
"share_target": {
"action": "/busca",
"method": "GET",
"params": { "title": "title", "text": "q", "url": "url" }
},
"shortcuts": [
{
"name": "Continuar de onde parei",
"short_name": "Continuar",
"url": "/educacao/dashboard?retomar=1&utm_source=pwa&utm_medium=atalho&utm_campaign=continuar"
}
]
}// No sw.js, o fetch faz "return" sem responder para /api/admin e /api/auth.
// Com rotas estáticas, esses pedidos nem acordam o service worker.
self.addEventListener("install", (event) => {
if ("addRoutes" in event) {
event.addRoutes([
{ condition: { urlPattern: "/api/admin/*" }, source: "network" },
{ condition: { urlPattern: "/api/auth/*" }, source: "network" },
{ condition: { urlPattern: "/*", requestMethod: "post" }, source: "network" },
]);
}
// o restante da instalação continua igual (pré-cache e skipWaiting)
});Do manifesto ao convite que funciona em todo aparelho
Quatro passos, cada um com reserva para o navegador que ainda não tem o recurso.
Passo 1: Identidade fixa para o app
O id do manifesto diz ao navegador que é sempre o mesmo app, mesmo que o endereço de início mude. O <install> não funciona sem ele.
Deu certo quando: O painel Application do DevTools mostra o id calculado igual ao que você escreveu.
Erro comum: Trocar o start_url numa campanha e o celular tratar como um segundo app.
Passo 2: Meça a abertura pelo ícone
Parâmetro de campanha no start_url e em cada atalho separa quem abre pelo app de quem chega pelo anúncio.
Deu certo quando: O relatório mostra visitas com utm_source=pwa e o atalho de origem.
Erro comum: Medir só a instalação e não saber se a pessoa volta.
Passo 3: Botão e reserva oferecidos juntos
O texto dentro do <install> aparece onde o elemento não existe. No iPhone, ele explica o caminho pelo menu de compartilhar.
Deu certo quando: Chrome mostra o botão; Safari mostra as instruções, sem tela vazia.
Erro comum: Esconder o convite inteiro onde o recurso falta.
Passo 4: Tire do service worker o que ele só deixa passar
API autenticada e envio de formulário vão para regras estáticas onde addRoutes existe; no resto, o if do fetch continua fazendo o mesmo.
Deu certo quando: O envio do formulário funciona igual com e sem o recurso.
Erro comum: Mandar /_next/static direto para a rede e perder a cópia que serve sem sinal.
No fim você tem: Um app que se instala com um toque onde o navegador permite, ensina o caminho onde não permite e mede quem volta pelo ícone.
Armadilhas
Instalar e funcionar sem rede, sem surpresa depois da publicação
Evitar
evitar
- HTML servido do cache primeiro, que pede arquivos apagados na publicação seguinte
- Contar com o <install> em produção depois do fim do teste de origem
- Manifesto sem id e start_url trocado a cada campanha
- Regra estática que manda tudo para a rede e apaga o modo sem sinal
- Versão do cache escrita à mão em vários lugares
Recomendado
fazer
- Página HTML com rede primeiro e cópia só na falha
- Reserva escrita dentro do elemento e detecção por HTMLInstallElement
- id fixo no manifesto e campanha só nos parâmetros do endereço
- Rotas estáticas só para o que o service worker já deixava passar
- Uma constante de versão e limpeza dos caches antigos na ativação
Aplicar os recursos ao projeto
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
IndexedDB guarda dados organizados dentro do navegador, com operações que terminam depois e transações. Uma transação junta várias alterações para que todas valham ou nenhuma valha, como um pedido fechado. Serve a rascunho e coleção maior que uma preferência, presa ao aparelho e às regras de armazenamento do navegador.
Chame indexedDB.open('manual', 1). Em onupgradeneeded, crie o depósito anotacoes com keyPath: 'id'. Depois, comece uma transação readwrite e chame objectStore('anotacoes').put({ id: 'capitulo-a', texto: 'Revisar proposta' }). Confirme em transaction.oncomplete e releia numa transação readonly. Assim a anotação do cliente sobrevive ao fechar a aba.
Feche a aba, reabra no mesmo endereço e procure o registro. Trate onerror e ofereça exportação para o que não pode sumir. Limpeza de dados e janela anônima mudam a durabilidade disso. Em arquivo aberto por duplo clique, não conte com uma identidade de endereço estável.
Dexie deixa o IndexedDB mais simples, com promessas e uma declaração clara da estrutura do banco. Promessa é uma operação que responde depois, sem travar a tela enquanto isso. A biblioteca corta código repetido e mantém os limites do armazenamento do navegador e o planejamento das mudanças na estrutura dos dados.
Declare const db = new Dexie('manual') e db.version(1).stores({ notas: 'id,capitulo' }). Grave com await db.table('notas').put({ id: 'nota-a', capitulo: 'cores', texto: 'Conferir contraste' }). Busque as notas daquele capítulo com where('capitulo').equals('cores').toArray(); capitulo virou índice para isso. Sem esse índice, a consulta varre tudo e demora.
Releia o registro depois de recarregar e force uma falha de gravação para ver a mensagem. Mudança de estrutura pede versão nova e, às vezes, migração dos dados. Dexie não sincroniza com servidor sozinho; deixe exportação e recuperação prontas quando a anotação valer o trabalho.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
localStorage guarda textinhos curtos ligados ao endereço da página, como um bilhete na porta. Cabe para tema escolhido ou último capítulo lido, quando perder o valor não estraga nada. A leitura trava a tela enquanto acontece, então nada de volume; o navegador também pode apagar tudo sem avisar você.
Ao trocar o tema, rode localStorage.setItem('tema', 'escuro') dentro de try/catch. Na abertura, leia getItem('tema') e aceite só claro ou escuro; qualquer outra coisa cai na preferência do sistema. Se a gravação falhar, guarde a escolha na memória daquela visita e deixe o botão funcionando assim mesmo.
Recarregue a página, bloqueie o armazenamento no navegador e teste de novo. Nenhuma falha pode impedir a leitura do conteúdo. Em endereço file:, esse comportamento varia de navegador para navegador e some ao mover o arquivo. Nunca use localStorage como cofre de senha ou de documentos.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
Service worker é um ajudante que fica entre a página e a rede, dentro do endereço registrado. Ele intercepta pedidos e pode devolver arquivos guardados no cache. Assim o site funciona sem internet depois da primeira visita. Pôr a PWA na tela inicial é outra coisa; o cache roda sem instalar nada.
A partir de um endereço HTTPS, registre navigator.serviceWorker.register('/sw.js'). No evento install, use event.waitUntil para esperar caches.open('manual-v1') e addAll dos arquivos que importam. No evento fetch, atenda só os pedidos previstos, devolvendo o arquivo guardado ou indo à rede. Planeje a limpeza dos caches velhos na ativação.
Confira o escopo, espere a ativação e teste uma página já controlada com a internet desligada. A primeira visita sem rede não baixa o que nunca foi guardado, e a tela fica vazia. Nunca jogue login e dado privado no cache. Registro exige endereço adequado; duplo clique não serve para registrar nada.
Yjs oferece estruturas compartilhadas que juntam edições feitas ao mesmo tempo sem perder nada. Esse modelo se chama CRDT: regras que deixam as mudanças chegarem em qualquer ordem e ainda assim fecharem igual. Transporte, login, gravação e regra de negócio continuam por sua conta, fora da biblioteca.
Crie dois documentos com new Y.Doc(). No primeiro, pegue getText('nota') e insira uma frase com insert(0, texto). Gere a atualização com Y.encodeStateAsUpdate(documentoA) e aplique no segundo com Y.applyUpdate(documentoB, atualizacao). Leia getText('nota').toString() nos dois. Num produto real, um provedor faz essa troca entre os aparelhos sozinho.
Altere os dois documentos e troque atualizações nos dois sentidos; depois veja se o texto fecha igual. Fechar igual não decide quem podia editar nem barra um valor proibido pela regra do negócio. Planeje gravação, reconexão e controle de acesso. Estado só na memória some ao fechar a aplicação.
A primeira visita offline depende do que já foi salvo
Compare rede e cache local nesta simulação. Instalar um aplicativo não cria automaticamente os arquivos necessários para trabalhar sem conexão.
A rede entrega a página. Salve os arquivos de exemplo antes de simular outra visita offline.
A fila é apenas um estado local da demonstração. Um produto precisa implementar armazenamento, reenvio, prevenção de duplicatas e confirmação do servidor.
Seu caderno neste capítulo
Abrir o caderno completoSelecione um trecho do capítulo para destacar ou anotar. Nos vídeos e áudios, use Anotar este momento. No teclado, selecione com Shift e as setas e use Alt+Shift+D para destacar ou Alt+Shift+N para anotar.
Salvo neste navegador. Entre na sua conta para levar o caderno a outros aparelhos.
Entre na sua conta para compartilhar o que aprendeu e convidar alguém para estudar com você.
Conexões deste capítulo
Veja o que estudar antes e para onde seguir depois, explore os conceitos e compare abordagens em outros cursos. Sugestões marcadas como “sugerido pelo grafo” vêm dos assuntos em comum, não do índice do curso.
Estude antes
- CursoClaude Code CLI: Programação com IA
- Montar vídeo em HTML com HyperFrames e escolher entre ele e o Remotionsugerido pelo grafoApresenta o conceito “HTML”, usado em “Construir um aplicativo instalável e resiliente”.
- CursoVídeo com IA: Claude Code, Codex e ElevenLabssugerido pelo grafo20 capítulos de “Frontends com Vibecoding” usam conceitos apresentados em “Vídeo com IA: Claude Code, Codex e ElevenLabs”.
- CursoNode.js: JavaScript no Servidorsugerido pelo grafo20 capítulos de “Frontends com Vibecoding” usam conceitos apresentados em “Node.js: JavaScript no Servidor”.
Depois, siga para
- CursoPrompt Engineering para Executivossugerido pelo grafo7 capítulos de “Prompt Engineering para Executivos” usam conceitos apresentados em “Frontends com Vibecoding”.
- CursoLLM FinOps: o custo da IA para quem assina o orçamentosugerido pelo grafo3 capítulos de “LLM FinOps: o custo da IA para quem assina o orçamento” usam conceitos apresentados em “Frontends com Vibecoding”.
Conceitos deste capítulo
O mesmo assunto em outros cursos
- MCP com Chrome: Automação com IAFazer o agente ler a página em texto em vez de fotografarExaminar conexões de Fazer o agente ler a página em texto em vez de fotografar
- Prompt Engineering para ExecutivosEscolher a técnica para fluxos que rodam por horasExaminar conexões de Escolher a técnica para fluxos que rodam por horas
- Vídeo com IA: Claude Code, Codex e ElevenLabsMontar vídeo em HTML com HyperFrames e escolher entre ele e o RemotionExaminar conexões de Montar vídeo em HTML com HyperFrames e escolher entre ele e o Remotion
- Software e IA para executivosManter vários sistemas de acordo quando um deles caiExaminar conexões de Manter vários sistemas de acordo quando um deles cai
Voltar ao capítulo anterior: Aplicar direção de arte, UX writing e padrões de código
Leve uma ideia para a prática
Escolha uma atividade no painel e volte a este curso quando quiser.
Atividades e evolução ficam reunidas no painel da sua conta.
Laboratórios ao vivo deste curso
Cada laboratório monta a biblioteca real dentro da aula, com controles para você mexer e o código do exemplo para copiar. O texto de reserva descreve a demonstração para quem lê sem JavaScript. O link abre o capítulo já no ponto do laboratório.
Base UI
Prenda o foco num diálogo sem escrever o comportamento
Abra a janela Agendar visita, percorra os campos com Tab, feche com Esc e acompanhe no painel onde o foco está e para onde ele volta.
Pacote
Abrir no capítuloConstruir componentes, usar o registro e publicar o catálogo@base-ui/reactLucide e Iconify
Mantenha uma família de ícones coerente e nomeie cada botão
Mude tamanho, traço e cor da barra, veja o símbolo do Iconify acompanhar o Lucide e rode a auditoria de nomes acessíveis.
Pacote
Abrir no capítuloProjetar uma linguagem de ícones e ilustraçãolucide-react, @iconify/reactMotion
Testar os três sinais que autorizam o terceiro degrau
Reproduza a entrada em sequência, aperte o botão com mola e arraste o cartão; ajuste rigidez e amortecimento e veja o que muda.
Pacote
Abrir no capítuloProjetar movimento, assinatura e narrativas por rolagemmotionVidstack
Ver o que separa um player de um vídeo cru
Dê o play, troque a velocidade e ligue a legenda; o painel ao lado mostra o estado que o player publica e que a etiqueta crua esconde.
Pacote
Abrir no capítuloProjetar movimento, assinatura e narrativas por rolagem@vidstack/reactcmdk
Achar um destino entre quarenta digitando três letras
Abra a paleta, digite fat e escolha um item só pelo teclado; o painel embaixo conta o que o filtro deixou passar e quanto tempo levou.
Pacote
Abrir no capítuloConstruir formulários e estados de interaçãocmdknumber-flow
Animar indicadores que mudam ao vivo com formato pt-BR
Veja três indicadores fictícios rolarem a cada troca e compare com o número em texto puro. Pause, reinicie e observe o separador de milhar.
Pacote
Abrir no capítuloProjetar gráficos e painéis pela decisão@number-flow/reactApache ECharts
Medir o custo de desenhar 200 mil pontos com o ECharts
Troque o tipo de gráfico e o volume de pontos, leia o tempo de desenho e alterne o eixo em zero. Mude o tema do site e veja as cores refazerem.
Pacote
Abrir no capítuloProjetar gráficos e painéis pela decisãoechartssharp e svgo
Escolher a variante certa da imagem e conferir o teto de 150 KB
Arraste a largura da tela simulada, troque a densidade entre 1x e 2x e veja qual arquivo o navegador escolhe, quanto ele pesa e se cabe no orçamento.
Pacote
Abrir no capítuloValidar desempenho, autenticação e segurançasharp, svgoReact Flow (xyflow)
Disparar um pedido e ver o orquestrador distribuir, conferir e responder
Alterne paralelo e sequencial, ligue e desligue a verificação e use a medição real; observe o tempo de parede em cada combinação.
Pacote
Abrir no capítuloConstruir as cenas do orquestrador, do paralelismo e do robô@xyflow/reactGSAP, Web Workers e number-flow
Dividir mil tarefas entre trabalhadores reais e correr três ritmos de geração
Execute com um trabalhador, depois com quatro e oito, e compare o tempo; em seguida percorra a corrida e separe a espera inicial do ritmo.
Pacote
Abrir no capítuloConstruir as cenas do orquestrador, do paralelismo e do robôgsap, @number-flow/reactThree.js com React Three Fiber, drei, Rapier e XR
Carregar o braço robótico, ver a física trabalhar e entrar na cena com o visor
Carregue a cena pelo botão, inicie o ciclo, mostre os ângulos das juntas, troque a câmera e a velocidade; com visor, entre em realidade virtual.
Pacote
Abrir no capítuloConstruir as cenas do orquestrador, do paralelismo e do robôthree, @react-three/fiber, @react-three/drei, @react-three/rapier, @react-three/xrMotion
Ver quatro agentes em raias trocando mensagens e a revisão devolvendo um trecho
Reproduza os 60 s de modelo, percorra o tempo pelo controle e esconda as mensagens para comparar a leitura; repare no tempo de parede contra a soma.
Pacote
Abrir no capítuloEspecificar, medir e produzir as cenas da máquinamotionMediaRecorder, Canvas 2D e Long Animation Frames (plataforma)
Medir o quadro da cena e gravar seis segundos dela em vídeo
Suba as partículas, force um bloqueio de 300 ms e leia o medidor; depois grave seis segundos, veja o codec escolhido e baixe o arquivo.
Pacote
Abrir no capítuloEspecificar, medir e produzir as cenas da máquinasem pacotesigma.js, graphology com ForceAtlas2 e cosmos.gl
Ver o grafo real do curso e um grafo de milhares de nós se organizarem em aglomerados
Rode o layout no grafo real, passe o mouse pelos nós e busque uma entidade; troque para 20 mil nós e leia o medidor; depois carregue o modo massivo na placa de vídeo.
Pacote
Abrir no capítuloAnimar um grafo de conhecimento amplo em movimentosigma, graphology, graphology-layout-forceatlas2, graphology-generators, @cosmos.gl/graph
Capítulos vizinhos em Frontends com Vibecoding
- 27Configurar ambiente, skills e o contêiner de contexto
- 28Aplicar direção de arte, UX writing e padrões de código
- 29Construir um aplicativo instalável e resiliente
- 30Produzir apresentações e PDF com critérios de entrega
- 31Construir as cenas do orquestrador, do paralelismo e do robô