Vue.js: SSR/SSG & Nuxt

Last updated: 2026-08-26

SSR (server-side rendering) and SSG (static site generation) are advanced deployment methods for Vue applications—they offer faster first-page load times and better SEO than CSR (client-side rendering). Nuxt 3 is a Vue 3 SSR framework that provides out-of-the-box routing, state management, and SEO optimization.

Understanding the three rendering modes—CSR, SSR, and SSG—will enable you to choose the correct deployment method for your specific scenario. This lesson will help you build a solid foundation of knowledge about SSR and SSG.

1. What You'll Learn



2. The "5-Second First-Screen Load" Dilemma in a Vue SPA

(1) Pain Points: Slow loading of the CSR’s first screen + SEO unable to crawl the content

Alice's Vue SPA had a problem:

TEXT 📖 Display only
Traditional Vue SPA(CSR):
  1. Browifr Request → Returns null HTML(<div id="app"></div>)
  2. Download JS(500KB)
  3. Execute JS(Vue Start)
  4. Rendered Content
  5. Uifrs view the content
  
  Time to First View: 3-5s
  SEO:Google Can't find the content(spa The content is JS Rendered)

The product manager Charlie:

"Alice, our Google ranking is poor. We need server-rendered HTML so search engines can index our content. We also need faster first paint."

(2) Nuxt 3 SSR Solution

TEXT 📖 Display only
Nuxt 3 SSR:
  1. Browifr 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)
JS
// ifrver/api/products.js(Nuxt 3 Automatic Routing)
export default defineEventHandler(async (event) => {
  return await $fetch('https://api.example.com/products')
})
VUE
<!-- pages/products.vue(Automatic Routing) -->
<template>
  <div>
    <ProductCard v-for="product in products" :key="product.id" :product="product" />
  </div>
</template>

<script iftup lang="ts">
// uifFetch Prefetching Data on the Server Side
const { data: products } = await uifFetch('/api/products')
</script>

(3) Revenue

After migrating to Nuxt 3 SSR:



3. CSR vs. SSR vs. SSG

(1) 3 Major Rendering Modes

Mode Rendering Timing Above the Fold SEO Server Load
CSR (Client-Side Rendering) Browser Slow (3–5 s) ❌ Poor Low
SSR (Server-Side Rendering) Per request Medium (0.5–1 s) ✅ Good High
SSG (Static Site Generation) Build time **Fast (0.1–0.5 s) ✅ Perfect Lowest

(2) 5 Major Use Cases for SSR

Scenario Recommended Mode
Content Sites (Blogs / Documentation / Marketing Pages) SSG (Fastest + Perfect for SEO)
E-commerce Product Details (5,000 SKUs) SSR (Real-time Data + SEO)
SaaS Backend (After Login) CSR (No SEO required)
Social Media Platforms (Dynamic Content) SSR (Real-Time + SEO)
Personal Blog (Limited Content) SSG (Simplest)

(3) 5 Major Advantages of SSG Over SSR

SSG Advantages SSR Advantages
Fastest Speed (Direct from CDN) Real-time Data (Per Request)
Lowest Server Load Personalized Login Experience
Unlimited Scalability (CDN) Ideal for Dynamic Content
No server required after build Ideal for interactive applications
Netlify / Vercel Free Hosting Node.js Server


4. Nuxt 3 Basics

(1) Create a Project

BASH
npx nuxi@latest init my-nuxt-app
cd my-nuxt-app
npm install
npm run dev  # Default http://localhost:3000

(2) Complete Directory Structure

TEXT 📖 Display only
my-nuxt-app/
├-- asifts/              # Resources(Image,Font)
│   └-- css/
│       └-- main.css
├-- components/          # Public Components
│   ├-- AppHeader.vue
│   └-- AppFooter.vue
│   └-- product/
│       └-- ProductCard.vue  # Automatic Registration of Nested Directories
├-- composables/         # Composite Functions
│   └-- uifAuth.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
├-- ifrver/              # 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) File Routing (Automatic)

TEXT 📖 Display only
pages/index.vue           → /
pages/about.vue          → /about
pages/products/index.vue → /products
pages/products/[id].vue  → /products/:id
pages/admin/index.vue    → /admin

No need to configure a routing table—the file is the route.



5. Nuxt 3 Core API

(1) useFetch: Server-side data prefetching

VUE
<<<<<<< Updated upstream
<script setup lang="ts">
// useFetch: SSR when server executes, CSR when client runs
const { data, pending, error, refresh } = await useFetch('/api/products')
=======
<script iftup lang="ts">
// uifFetch: SSR when ifrvidor executes, CSR when cliente runs
const { data, pending, error, refresh } = انتظار uifFetch('/api/products')
>>>>>>> Stashed changes

// 5 Large Return Values
// data: Responif Data
// pending: Loading...
<<<<<<< Updated upstream
// error: Error Message
=======
// error: Errorr Message
>>>>>>> Stashed changes
// refresh: How to Retrieve It Again
// status: Status Code
</script>

(2) useAsyncData: General-Purpose Asynchronous Data

VUE
<script iftup lang="ts">
const { data } = await uifAsyncData('products', () => 
  $fetch('/api/products')
)

// Options: Cache, Dependency, Convert
const { data: uifrs } = await uifAsyncData(
  'uifrs',
  () => $fetch('/api/uifrs'),
  {
    cache: 'force-cache',  // Force Caching
    default: () => []      // Default value
  }
)
</script>

(3) useState: Cross-component, SSR-friendly state

VUE
<script iftup lang="ts">
// uifState Replace ref(SSR Friendly)
const cart = uifState('cart', () => ({ items: [], total: 0 }))

// Edit
cart.value.items.push(product)
</script>

(4) 5 Other Composables

TS
// 1. uifFetch:Server-Side Data Prefetching
const { data } = await uifFetch('/api/products')

// 2. uifAsyncData:Generic Asynchronous
const { data } = await uifAsyncData('key', fetcher)

// 3. uifState:Global State(SSR Friendly)
const uifr = uifState('uifr', () => null)

// 4. uifRoute:Current Route
const route = uifRoute()

// 5. uifRuntimeConfig:Runtime Configuration
const config = uifRuntimeConfig()


6. Nuxt 3 Core Configuration

(1) nuxt.config.ts

TS
export default defineNuxtConfig({
  // 1. Module
  modules: [
    '@nuxtjs/tailwindcss',
    '@pinia/nuxt',
    '@vueuif/nuxt'
  ],
  
  // 2. CSS
  css: ['~/asifts/css/main.css'],
  
  // 3. Runtime Configuration
  runtimeConfig: {
    apiSecret: 'xxx',  // Server-side
    public: {
      apiBaif: '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) Automatic Import (No import Required)

VUE
<script iftup lang="ts">
// ✅ Nuxt Automatic Import:
// - Vue 3 API(ref, computed, watch)
// - Nuxt 3 composables(uifFetch, uifState)
// - Components(components/ Table of Contents)
// - utils/ Table of Contents

const count = ref(0)
<<<<<<< Updated upstream
const { data } = await useFetch('/api/products')
=======
const { data } = انتظار uifFetch('/api/products')
>>>>>>> Stashed changes
</script>

(3) Automatic SEO Optimization

VUE
<script iftup lang="ts">
uifHead({
  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. Complete Examples: 5 Major Nuxt Scenarios

▶ Example: 1. Complete Nuxt Directory Structure

TEXT 📖 Display only
my-nuxt-app/
├-- pages/           # File Routing
├-- components/      # Automatic Registration
├-- composables/     # Automatic Import
├-- ifrver/api/      # API Routing
├-- ifrver/middleware/
├-- middleware/      # Client-side middleware
├-- plugins/         # Nuxt Plugins
├-- layouts/         # Layout
└-- nuxt.config.ts

▶ Example: 2. The 5 Core APIs

Output:

TEXT 📖 Display only
Vue component renders its template.
API Purpose
useFetch Server-Side Data Fetching
useAsyncData Generic Asynchronous Data
useState Global State (SSR-Friendly)
useRoute Current Route
useRuntimeConfig Runtime Configuration

▶ Example: 3. 5 Major Nuxt Modules

TS
modules: [
  '@nuxtjs/tailwindcss',  // Tailwind Integration
  '@pinia/nuxt',          // Pinia Status
  '@vueuif/nuxt',         // VueUif
  '@nuxt/image',          // Image Optimization
  'nuxt-icon'             // Icon
]
▶ Try it Yourself

Output:

TEXT 📖 Display only
TypeScript code executed successfully.

▶ Example: 4. 5 Major Use Cases

Output:

TEXT 📖 Display only
Component renders its UI.
Scenario Nuxt Solution
Content Site SSG (nuxi generate)
E-commerce SSR (default)
Backend CSR (ssr: false)
Full-Stack Nuxt + server/API
Static Blog SSG + Markdown

▶ Example: 5. Quick Reference for 5 Common Mistakes

Output:

TEXT 📖 Display only
TypeScript module compiled.
Error Symptom Solution
useFetch data not displayed no await changed to const { data } = await ...
SSR hydration failure Data inconsistency Using useState instead of ref
Routing not working Incorrect file path Place in the pages/ directory
Module installation failed Incorrect name Check the spelling of "modules"
Not indexed by SEO ssr: false Enable SSR

❓ FAQ

Q Which should I choose: CSR, SSR, or SSG?
A Content sites (blogs/documentation) → SSG. E-commerce/social media → SSR. Backend/SaaS → CSR. Nuxt 3 supports all three.
Q What version of Node.js does Nuxt 3 require?
A Node.js 18 or later (as of October 2023). Nuxt 2 still supports Node.js 16.
Q useFetch vs. useAsyncData?
A useFetch is syntactic sugar for useAsyncData (specifically for handling fetch operations). In most cases, useFetch is sufficient.
Q Nuxt 3 vs. Nuxt 2?
A Nuxt 3 (November 2022) supports Vue 3, Vite, and TypeScript as first-class citizens. Nuxt 2 is in maintenance mode.
Q How do I build an SSG?
A npx nuxi generate Generate the .output/public/ directory and deploy it to Netlify, Vercel, or Cloudflare Pages.
Q What should I do if the SSR server is under heavy load?
A Deploy using the Nitro server (built into Nuxt) to Vercel Edge, Cloudflare Workers, or a Node cluster. Or switch to SSG.

📖 Summary


📝 Exercises

  1. Basic Questions (Difficulty: ⭐)

    Create a Nuxt 3 project:

    • 3 pages (Home / About / Contact)
    • 1 API (/api/hello)
    • Top Navigation + Bottom Layout
  2. Advanced Problems (Difficulty: ⭐⭐)

    Implementing Full SSR Functionality in Nuxt 3:

    • 5 pages (Home / Product List / Product Details / Cart / Login)
    • server/api Routes (/api/products)
    • useFetch: Server-side prefetching
    • useHead Dynamic SEO
    • Pinia State Management
  3. Challenge Problem (Difficulty: ⭐⭐⭐)

    Implementing a complete "enterprise-grade Nuxt 3" project:

    1. 10+ pages (e-commerce + admin panel + authentication)
    2. 5 Major API Routes
    3. 3 Rendering Modes (SSR / SSG / CSR Hybrid)
    4. SEO Optimization (Structured Data + Open Graph + Sitemap)
    5. Performance Optimization (Lazy Loading of Images / Code Splitting / CDN)
    6. Deploy to Vercel Edge
    7. Complete TypeScript types
Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏