📚 Módulo 10: Mobile/PWA - Transformando Next.js em um Progressive Web App
Neste módulo avançado da TecLoja 04 (Enterprise Stack), iniciaremos a ponte de expansão móvel do nosso ecossistema Next.js e NestJS. Ao invés de criarmos uma aplicação móvel híbrida ou nativa separada, aproveitaremos a arquitetura SSR (Server-Side Rendering) do Next.js para transformá-lo em um PWA (Progressive Web App) nativo e instalável diretamente na tela inicial do celular do usuário.
Configuraremos as regras do Manifesto da Web App, integraremos suporte a Service Workers com o plugin moderno @ducanh2912/next-pwa e auditaremos o projeto utilizando as ferramentas do Google Lighthouse e o Chrome DevTools.
🗺️ 1. Arquitetura PWA e Ciclo de Vida do Service Worker
O diagrama abaixo descreve a comunicação entre a aplicação Next.js, o Service Worker que atua em segundo plano no navegador e a API NestJS:
flowchart TD
%% Styling
classDef client fill:#000000,stroke:#333333,stroke-width:2px,color:#ffffff;
classDef sw fill:#FF9800,stroke:#E65100,stroke-width:2px,color:#ffffff;
classDef nest fill:#E0234E,stroke:#9F1239,stroke-width:2px,color:#ffffff;
subgraph Browser_Sandbox ["🌐 Sandbox do Navegador do Usuário"]
A[Next.js Client UI]:::client <-->|Interagir / Mensagens| B[Service Worker Background Thread]:::sw
B <-->|Interromper Requisições Cache-First| C[(Cache Storage do PWA)]:::sw
end
subgraph Backend_Server ["⚙️ Infraestrutura Externa"]
B <-->|Consultas de Rede fallback| D[API NestJS / Banco Neon]:::nest
end
📄 2. Criação do Manifesto Web (manifest.json)
O arquivo de manifesto informa ao sistema operacional do celular (Android/iOS) que o site se comporta como um aplicativo instalável, definindo o nome, as cores do sistema e os ícones de exibição na tela inicial.
Crie o arquivo /public/manifest.json no seu repositório frontend Next.js:
{
"theme_color": "#0f172a",
"background_color": "#0f172a",
"display": "standalone",
"scope": "/",
"start_url": "/",
"name": "TecLoja 04 Enterprise",
"short_name": "TecLoja 04",
"description": "E-commerce corporativo de tecnologia de alta performance.",
"orientation": "portrait",
"icons": [
{
"src": "/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
]
}
Nota: Lembre-se de salvar os ícones correspondentes de tamanhos 192px e 512px dentro da pasta /public/icons/.
⚙️ 3. Integração do @ducanh2912/next-pwa no Next.js
Para injetar as rotinas de Service Worker em nosso pipeline de compilação sem gerenciar arquivos JavaScript complexos manualmente, utilizaremos a biblioteca de PWA recomendada para a arquitetura App Router do Next.js.
Instalação
Na raiz do repositório frontend, execute:
npm install @ducanh2912/next-pwa
Configurando o next.config.js
Edite o seu arquivo de configuração next.config.js envelopando as opções com o gerador de PWA:
const withPWA = require("@ducanh2912/next-pwa").default({
dest: "public",
disable: process.env.NODE_ENV === "development", // Desativar em dev para evitar travamentos de cache de código
register: true,
skipWaiting: true,
});
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
// Outras configurações do Next.js
};
module.exports = withPWA(nextConfig);
🌐 4. Metadados Globais no Layout do Next.js
Para que o navegador do smartphone reconheça as regras de PWA, devemos declarar as chaves e os links do manifesto no cabeçalho HTML de nossa aplicação. Abra seu arquivo de layout principal /app/layout.tsx e atualize o objeto de metadados:
import type { Metadata, Viewport } from "next";
export const metadata: Metadata = {
title: "TecLoja 04",
description: "E-commerce corporativo de tecnologia de alta performance.",
manifest: "/manifest.json",
appleWebApp: {
capable: true,
statusBarStyle: "default",
title: "TecLoja 04",
},
};
export const viewport: Viewport = {
themeColor: "#0f172a",
width: "device-width",
initialScale: 1,
maximumScale: 1,
userScalable: false,
};
✅ Pré-Requisitos deste Módulo
Antes de rodar as ferramentas de auditoria de PWA, verifique se:
- A aplicação Next.js passa com sucesso no build de produção local (
npm run build). - Você possui o navegador Google Chrome instalado (necessário para ferramentas do Lighthouse e DevTools).
🤔 Por que fizemos assim?
- Por que escolher PWA ao invés de construir um aplicativo React Native? Em grandes plataformas corporativas de e-commerce, o funil de conversão é crítico. Forçar o usuário a baixar um aplicativo de 40MB da loja de aplicativos para fazer uma única compra rápida resulta em um abandono de carrinho de até 50%. PWAs são carregados instantaneamente via navegador e podem ser instalados com um único clique (pesando menos de 1MB), mantendo a experiência idêntica a de um aplicativo de loja.
- Por que desativar o PWA no ambiente de desenvolvimento? Durante as aulas de desenvolvimento ou ajustes finos de código CSS, o Service Worker realiza caching severo de arquivos JavaScript e folhas de estilo. Deixar o PWA ativo em desenvolvimento forçaria o estudante a limpar o cache do navegador a cada modificação, reduzindo o dinamismo de aprendizado.
🔍 Checkpoint
- Geração de Service Worker: Execute
npm run buildseguido pornpm run startlocalmente. Abra a URL do servidor no Chrome, abra o DevTools (F12 -> Application -> Service Workers) e confirme se o service worker consta como ativo e registrado. - Auditoria Lighthouse: No console do Chrome DevTools, navegue até a aba Lighthouse, marque apenas a opção “Progressive Web App” e dispare a auditoria. O site deve pontuar com o selo verde de PWA validado pelo Google.
⚠️ Erros Comuns
| Erro | Causa | Solução |
|---|---|---|
| O ícone de instalação “Adicionar à Tela Inicial” não é exibido | Ícones de manifesto ausentes na pasta /public/icons/ ou tamanho do ícone diferente dos formatos exigidos no arquivo JSON. |
Certifique-se de salvar imagens no formato estrito PNG de 192x192px e 512x512px. |
| O Service Worker exibe erros de rede claros no console (Cleartext) | PWAs exigem conexão estritamente segura para registro de Service Workers por motivos de segurança cibernética. | Em ambiente de desenvolvimento local, o Chrome permite registrar sob http://localhost. Em ambientes de deploy na nuvem, você deve forçar o acesso via protocolo HTTPS (Vercel ou Netlify cuidam disso por padrão). |
TypeError: Cannot read property 'default' of require(...) no console do terminal de build |
Confusão entre importações de padrão ESM e CommonJS na configuração do arquivo next.config.js. |
Importe usando o sufixo .default conforme detalhado na seção de setup de código do módulo. |