Vue.js: SSR/SSG e Nuxt
Última atualização: 2026-10-20
SSR (renderização do lado do servidor) e SSG (geração de sites estáticos) são métodos avançados de implantação para aplicativos Vue — eles oferecem tempos de carregamento da primeira página mais rápidos e melhor SEO do que a CSR (renderização do lado do cliente). O Nuxt 3 é um framework Vue 3 para SSR que oferece roteamento, gerenciamento de estado e otimização de SEO prontos para uso.
Compreender os três modos de renderização — CSR, SSR e SSG — permitirá que você escolha o método de implantação correto para o seu cenário específico. Esta lição ajudará você a construir uma base sólida de conhecimento sobre SSR e SSG.
1. O que você vai aprender
- Comparação dos três principais modos de renderização: CSR, SSR e SSG
- 5 principais casos de uso do SSR
- Estrutura completa de diretórios do Nuxt 3
- APIs Composable do Nuxt 3 (useState / useFetch / useAsyncData)
- Importação automática no Nuxt + roteamento de arquivos
- Ecossistema de módulos do Nuxt (@nuxtjs/tailwindcss, etc.)
- 5 erros comuns
2. O dilema do “carregamento da primeira tela em 5 segundos” em um SPA Vue
(1) Pontos críticos: Carregamento lento da primeira tela do CSR + o SEO não consegue rastrear o conteúdo
O Vue SPA da Alice tinha um problema:
Traditional Vue SPA(CSR):
1. Browser Request → Returns null HTML(<div id="app"></div>)
2. Download JS(500KB)
3. Execute JS(Vue Start)
4. Rendered Content
5. Users view the content
Time to First View: 3-5s
SEO:Google Can't find the content(spa The content is JS Rendered)
O gerente de produto Charlie:
“Alice, nossa classificação no Google está ruim. Precisamos de HTML renderizado pelo servidor para que os mecanismos de busca possam indexar nosso conteúdo. Também precisamos de um ‘first paint’ mais rápido.”
(2) Solução de SSR para o Nuxt 3
Nuxt 3 SSR:
1. Browser Request → Server-Side Rendering Complete HTML
2. Return with content HTML (Home Page 0.5s)
3. Download JS(hydration Required)
4. Client"Activate"(Take Over Interaction)
Time to First View: 0.5s
SEO:✅ Perfect(HTML Contents)
// server/api/products.js(Nuxt 3 Automatic Routing)
export default defineEventHandler(async (event) => {
return await $fetch('https://api.example.com/products')
})
(3) Receita
Após a migração para o Nuxt 3 com SSR:
- Tempo até o primeiro conteúdo visível: 3–5 segundos → 0,5 segundos (-90%)
- Pontuação de SEO: 60 → 95 (+35)
- Indexadas pelo Google: 0 páginas → Todas as 5.000 páginas de SKUs (+∞)
- Compartilhamento nas redes sociais: 0 cartões → Visualização completa (Open Graph)
3. CSR x SSR x SSG
(1) Os 3 principais modos de renderização
| Modo | Tempo de renderização | Acima da dobra | SEO | Carga do servidor |
|---|---|---|---|---|
| CSR (Renderização no lado do cliente) | Navegador | Lento (3–5 s) | ❌ Ruim | Baixo |
| SSR (Renderização no lado do servidor) | Por solicitação | Médio (0,5–1 s) | ✅ Bom | Alto |
| SSG (Geração de sites estáticos) | Tempo de compilação | **Rápido (0,1–0,5 s) | ✅ Perfeito | O menor |
(2) 5 principais casos de uso do SSR
| Cenário | Modo recomendado |
|---|---|
| Sites de conteúdo (blogs / documentação / páginas de marketing) | SSG (Mais rápido + ideal para SEO) |
| Detalhes de produtos de comércio eletrônico (5.000 SKUs) | SSR (Dados em tempo real + SEO) |
| Back-end de SaaS (após o login) | CSR (não requer SEO) |
| Plataformas de mídia social (conteúdo dinâmico) | SSR (em tempo real + SEO) |
| Blog pessoal (conteúdo limitado) | SSG (o mais simples) |
(3) As 5 principais vantagens do SSG em relação ao SSR
| Vantagens do SSG | Vantagens do SSR |
|---|---|
| Velocidade máxima (diretamente do CDN) | Dados em tempo real (por solicitação) |
| Menor carga no servidor | Experiência de login personalizada |
| Escalabilidade ilimitada (CDN) | Ideal para conteúdo dinâmico |
| Não requer servidor após a compilação | Ideal para aplicativos interativos |
| Hospedagem gratuita no Netlify / Vercel | Servidor Node.js |
4. Noções básicas do Nuxt 3
(1) Criar um projeto
npx nuxi@latest init my-nuxt-app
cd my-nuxt-app
npm install
npm run dev # Default http://localhost:3000
(2) Estrutura completa de diretórios
my-nuxt-app/
├-- assets/ # Resources(Image,Font)
│ └-- css/
│ └-- main.css
├-- components/ # Public Components
│ ├-- AppHeader.vue
│ └-- AppFooter.vue
│ └-- product/
│ └-- ProductCard.vue # Automatic Registration of Nested Directories
├-- composables/ # Composite Functions
│ └-- useAuth.ts
├-- layouts/ # Layout
│ ├-- default.vue # Default Layout
│ └-- admin.vue # Backend Layout
├-- middleware/ # Routing Middleware
│ └-- auth.ts
├-- pages/ # File Routing(Automatically Generated)
│ ├-- index.vue # /
│ ├-- about.vue # /about
│ ├-- products/
│ │ ├-- index.vue # /products
│ │ └-- [id].vue # /products/:id
│ └-- admin/
│ └-- index.vue # /admin
├-- plugins/ # Nuxt Plugins
│ └-- pinia.ts
├-- public/ # Static Resources
├-- server/ # Server-side code
│ ├-- api/ # API Routing(Automatic Registration)
│ │ └-- products.ts # /api/products
│ └-- middleware/ # Server-Side Middleware
├-- stores/ # Pinia stores
├-- app.vue # Root Component
├-- nuxt.config.ts # Nuxt Layout
└-- package.json
(3) Encaminhamento de arquivos (automático)
pages/index.vue → /
pages/about.vue → /about
pages/products/index.vue → /products
pages/products/[id].vue → /products/:id
pages/admin/index.vue → /admin
Não é preciso configurar uma tabela de roteamento — o arquivo é a rota.
▶ Exemplo: Estrutura completa de diretórios do Nuxt
my-nuxt-app/
├-- pages/ # File Routing
├-- components/ # Automatic Registration
├-- composables/ # Automatic Import
├-- server/api/ # API Routing
├-- server/middleware/
├-- middleware/ # Client-side middleware
├-- plugins/ # Nuxt Plugins
├-- layouts/ # Layout
└-- nuxt.config.ts
Saída:
nuxi dev sobe o projeto em http://localhost:3000.
pages/index.vue vira a rota / e pages/products.vue vira /products, sem arquivo de rotas.
Arquivos em components/ e composables/ são importados automaticamente; server/api/hello.ts responde em /api/hello.
(1) 📊 2. As 5 APIs principais
| API | Finalidade |
|---|---|
useFetch |
Obtenção de dados no lado do servidor |
useAsyncData |
Dados assíncronos genéricos |
useState |
Estado global (compatível com SSR) |
useRoute |
Rota atual |
useRuntimeConfig |
Configuração de tempo de execução |
5. API principal do Nuxt 3
(1) useFetch: Pré-busca de dados no lado do servidor
<script setup lang="ts">
// useFetch: SSR when server executes, CSR when client runs
const { data, pending, error, refresh } = await useFetch('/api/products')
// 5 Large Return Values
// data: Response Data
// pending: Loading...
// error: Error Message
// refresh: How to Retrieve It Again
// status: Status Code
</script>
(2) useAsyncData: Dados assíncronos de uso geral
<script setup lang="ts">
const { data } = await useAsyncData('products', () =>
$fetch('/api/products')
)
// Options: Cache, Dependency, Convert
const { data: users } = await useAsyncData(
'users',
() => $fetch('/api/users'),
{
cache: 'force-cache', // Force Caching
default: () => [] // Default value
}
)
</script>
(3) useState: estado compartilhado entre componentes e compatível com SSR
<script setup lang="ts">
// useState Replace ref(SSR Friendly)
const cart = useState('cart', () => ({ items: [], total: 0 }))
// Edit
cart.value.items.push(product)
</script>
(4) 5 Outros componentes
// 1. useFetch:Server-Side Data Prefetching
const { data } = await useFetch('/api/products')
// 2. useAsyncData:Generic Asynchronous
const { data } = await useAsyncData('key', fetcher)
// 3. useState:Global State(SSR Friendly)
const user = useState('user', () => null)
// 4. useRoute:Current Route
const route = useRoute()
// 5. useRuntimeConfig:Runtime Configuration
const config = useRuntimeConfig()
▶ Exemplo: Lista de produtos com useFetch
▶ ExperimenteSaída:
Primeira visita: o HTML já chega com a lista de produtos (SSR, sem "Carregando...").
Navegação pelo cliente: "Carregando..." aparece enquanto pending é true.
Clique em Atualizar → refresh() refaz a requisição e a lista é trocada.
6. Configuração básica do Nuxt 3
(1) nuxt.config.ts
export default defineNuxtConfig({
// 1. Module
modules: [
'@nuxtjs/tailwindcss',
'@pinia/nuxt',
'@vueuse/nuxt'
],
// 2. CSS
css: ['~/assets/css/main.css'],
// 3. Runtime Configuration
runtimeConfig: {
apiSecret: 'xxx', // Server-side
public: {
apiBase: 'https://api.example.com' // Client
}
},
// 4. Rendering Mode
ssr: true, // Enable SSR
// 5. Application Configuration
app: {
head: {
title: 'My App',
meta: [
{ name: 'description', content: 'My app description' }
]
}
}
})
(2) Importação automática (não é necessário import)
<script setup lang="ts">
// ✅ Nuxt Automatic Import:
// - Vue 3 API(ref, computed, watch)
// - Nuxt 3 composables(useFetch, useState)
// - Components(components/ Table of Contents)
// - utils/ Table of Contents
const count = ref(0)
const { data } = await useFetch('/api/products')
</script>
(3) Otimização automática para SEO
<script setup lang="ts">
useHead({
title: 'iPhone 15 Pro - My Shop',
meta: [
{ name: 'description', content: 'Buy iPhone 15 Pro at best price' },
{ property: 'og:title', content: 'iPhone 15 Pro' },
{ property: 'og:image', content: '/iphone.jpg' }
]
})
</script>
7. Exercício abrangente: módulos essenciais do Nuxt
▶ Exemplo: 5 Principais módulos do Nuxt
modules: [
'@nuxtjs/tailwindcss', // Tailwind Integration
'@pinia/nuxt', // Pinia Status
'@vueuse/nuxt', // VueUse
'@nuxt/image', // Image Optimization
'nuxt-icon' // Icon
]
Saída:
Após reiniciar o dev server, os 5 módulos ficam ativos.
Classes do Tailwind funcionam, o Pinia é registrado e useFetch já está disponível.
NuxtImg otimiza as imagens e o módulo de ícones permite usar <Icon name="..." />.
(2) 📊 4. 5 Principais casos de uso
| Cenário | Solução Nuxt |
|---|---|
| Site de conteúdo | SSG (nuxi generate) |
| Comércio eletrônico | SSR (padrão) |
| Backend | CSR (ssr: false) |
| Full-Stack | Nuxt + servidor/API |
| Blog estático | SSG + Markdown |
(3) 📊 5. Referência rápida para 5 erros comuns
| Erro | Sintoma | Solução |
|---|---|---|
| Dados do useFetch não exibidos | sem await | alterado para const { data } = await ... |
| Falha na hidratação do SSR | Inconsistência nos dados | Uso de useState em vez de ref |
| O roteamento não está funcionando | Caminho do arquivo incorreto | Coloque no diretório pages/ |
| Falha na instalação do módulo | Nome incorreto | Verifique a grafia de “módulos” |
| Não indexado por SEO | ssr: false | Ativar SSR |
❓ Perguntas Frequentes
npx nuxi generate Gere o diretório .output/public/ e faça a implantação no Netlify, Vercel ou Cloudflare Pages.📖 Resumo
- CSR / SSR / SSG: Os três principais modos de renderização: CSR (3–5 segundos para o carregamento da primeira tela) / SSR (0,5–1 segundo) / SSG (0,1–0,5 segundos)
- 5 principais casos de uso do SSR: comércio eletrônico / redes sociais / dados em tempo real / status de login / conteúdo dinâmico
- O Nuxt 3 é o framework oficial de SSR para o Vue 3
- Roteamento de arquivos: o diretório “pages/” é a rota
- 5 APIs principais: useFetch / useAsyncData / useState / useRoute / useRuntimeConfig
- Importação automática: API do Vue + composíveis do Nuxt + componentes + utilitários
- Ecossistema de módulos do Nuxt: mais de 200 módulos oficiais e da comunidade
- Otimização automática de SEO: configuração dinâmica do useHead
📝 Exercícios
-
Questões básicas (Dificuldade: ⭐)
Crie um projeto Nuxt 3:
- 3 páginas (Página inicial / Sobre / Contato)
- 1 API (/api/hello)
- Navegação superior + Layout inferior
-
Problemas avançados (Dificuldade: ⭐⭐)
Implementação da funcionalidade completa de SSR no Nuxt 3:
- 5 páginas (Página inicial / Lista de produtos / Detalhes do produto / Carrinho / Login)
- Rotas do servidor/API (/api/products)
- useFetch: pré-busca no lado do servidor
- useHead SEO dinâmico
- Gestão Estadual de Pinia
-
Problema de desafio (Dificuldade: ⭐⭐⭐)
Implementação de um projeto completo do “Nuxt 3 para empresas”:
- Mais de 10 páginas (comércio eletrônico + painel de administração + autenticação)
- As 5 principais rotas da API
- 3 modos de renderização (SSR / SSG / CSR híbrido)
- Otimização para SEO (Dados Estruturados + Open Graph + Mapa do site)
- Otimização de desempenho (carregamento diferido de imagens / divisão de código / CDN)
- Implantar no Vercel Edge
- Tipos completos do TypeScript