📚 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:


🤔 Por que fizemos assim?


🔍 Checkpoint

  1. Geração de Service Worker: Execute npm run build seguido por npm run start localmente. 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.
  2. 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.

Voltar para o Sumário