SSR and Nuxt Intro
Introduction
A standard Vite + Vue SPA ships one index.html and renders entirely in the browser. Server-side rendering (SSR) generates HTML on the server for each request—better for SEO, social previews, and first paint. Nuxt 3 is the official Vue meta-framework for SSR, SSG, and full-stack features. This is a thin overview—full Nuxt tutorials live in Nuxt documentation.
Prerequisites
- Build, Preview, and Deploy
- Vue Router Basics
- Completed SPA chapters 01–18
CSR vs SSR vs SSG
| Mode | Where HTML is built | First request |
|---|---|---|
| CSR (client-only SPA) | Browser | Empty shell → JS downloads → render |
| SSR | Server per request | Full HTML with content |
| SSG | Build time | Static HTML files (like SPA + pre-render) |
Hello Code Vue track teaches CSR with Vite—simplest path to learn Vue and pair with separate FastAPI APIs.
When You Need SSR
| Need | Consider |
|---|---|
| Public marketing pages, SEO keywords | SSR or SSG |
| Social share cards (Open Graph) | SSR/SSG with meta tags |
| Authenticated admin dashboard | CSR SPA is often enough |
| Public blog index crawled by Google | SSR, SSG, or pre-render |
Many teams ship CSR admin + SSG marketing as separate apps.
What Nuxt Adds
| Feature | SPA (Vue Router) | Nuxt 3 |
|---|---|---|
| Routing | Manual routes array | File-based pages/ |
| Data fetching | onMounted + fetch | useFetch, useAsyncData |
| SSR | Manual setup | Built-in |
| API routes | Separate backend | Optional server/api/ |
| Meta / SEO | @vueuse/head or manual | useSeoMeta |
Nuxt Project Sketch
npm create nuxt@latest hello-nuxt
cd hello-nuxt
npm run devhello-nuxt/
├── nuxt.config.ts
├── app.vue
├── pages/
│ ├── index.vue → /
│ └── posts/[slug].vue → /posts/:slug
└── server/
└── api/
└── health.get.ts → /api/healthpages/index.vue:
<script setup lang="ts">
const { data: posts } = await useFetch("/api/posts");
</script>
<template>
<ul>
<li v-for="post in posts" :key="post.id">{{ post.title }}</li>
</ul>
</template>Code explanation:
- Top-level
awaitinscript setupworks with NuxtuseFetch - Server can fetch before HTML is sent—no loading flash for first paint
useFetch vs onMounted fetch
SPA pattern:
<script setup lang="ts">
import { onMounted, ref } from "vue";
const posts = ref([]);
onMounted(async () => {
posts.value = await fetch("/api/posts").then((r) => r.json());
});
</script>Nuxt useFetch runs on server and client, handles serialization and hydration.
Hydration
SSR sends HTML + embedded state. Client Vue hydrates—attaches listeners to existing DOM.
Hydration mismatch warning means server HTML ≠ client render—fix conditional rendering, dates, or random IDs.
Warning
Do not use window or localStorage during SSR without guards—crashes on server.
if (import.meta.client) {
// browser-only code
}In Nuxt: import.meta.client or <ClientOnly> component.
SSG with Nuxt
npm run generateOutputs static dist/—host like any SPA. Good for docs and blogs with known routes.
Nuxt vs Staying on Vite SPA
| Stay on Vite SPA | Move to Nuxt |
|---|---|
| Learning Vue core | Need SEO/SSR |
| API already in FastAPI/Django | Want full-stack in one repo |
| Simple deploy (static files) | OK with Node server for SSR |
You can learn Vue deeply on this track, then adopt Nuxt when requirements demand SSR.
Related Hello Code Tracks
- Backend stays separate: FastAPI with PostgreSQL, Django REST
- Deploy: Nginx, Docker
FAQ
Is Nuxt required for Vue jobs?
Many jobs use Vite SPA or Nuxt—both are Vue. Know SPA first; Nuxt adds conventions.
Nuxt replace Pinia?
No—Nuxt works with Pinia. @pinia/nuxt module auto-imports stores.
API in Nuxt server vs FastAPI?
Nuxt server/api for small BFF layers; complex domains often stay in Python/Java APIs.
Vue 3 skills transfer?
Yes—SFC, Composition API, Pinia, same Vue core.
Incremental adoption?
Hard to SSR-wrap existing Vite SPA—usually new Nuxt project or pre-render subset.
Official next step?
Nuxt 3 docs — Introduction and Data Fetching sections.