Frontend Development 21 min read

Understanding Server-Side Rendering (SSR) with Nuxt: Features, Setup, and Best Practices

This article explains the concept of Server‑Side Rendering (SSR), why it improves SEO and first‑paint performance, compares popular SSR‑compatible frameworks, and provides a step‑by‑step guide for initializing a Nuxt project, configuring routing, SEO, styling, data fetching, state management, and extending functionality with modules.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Understanding Server-Side Rendering (SSR) with Nuxt: Features, Setup, and Best Practices

What is SSR (Server‑Side Rendering)?

SSR means rendering the full HTML of a page on the server before sending it to the client, similar to traditional Java/ASP.NET/PHP approaches. Modern SSR is tightly coupled with front‑end frameworks like Vue or React and uses Node.js to render pages or components in a universal way.

Why use SSR?

SEO: Search engines such as Google , 百度 , Yandex , Bing and Yahoo can crawl a fully rendered page, improving indexability.

First‑paint speed: Unlike SPA, SSR returns a ready‑to‑display HTML, reducing the time before users see content.

Frameworks that support SSR

Open‑source library

Supported language

Stars

Description

Nuxt

Vue

54.9k

Fast scaffolding, type‑safe, high performance, extensible

Next

React

127k

Established framework, rich ecosystem, data‑fetch, styling

Quasar

Vue

26k

Rich UI, supports desktop and mobile

Remix

React

29.9k

Ultimate UX, zero‑config

What is Nuxt?

Nuxt is the leading full‑stack framework for Vue, offering out‑of‑the‑box SSR, file‑based routing, automatic imports, and a built‑in data‑fetch API. It mirrors Vue’s CSR development experience while handling SSR automatically.

File‑based routing: place pages in pages/ (e.g., pages/index.vue , pages/about.vue ).

Code splitting via Vue’s Virtual DOM, generating minimal chunks for faster load.

SSR is built‑in: develop as you would a CSR Vue app.

Automatic component import – no manual import Card from './Card.vue' needed.

Composable useFetch API for unified client/server data fetching.

Default Vite build, with optional Webpack or Rspack.

Nuxt’s architecture mirrors vue/core and splits functionality into packages such as nuxt (core engine), @nuxt/vite-builder , nuxt/webpack-builder , @nuxt/rspack-builder , nuxi (CLI), nitro (server engine), and @nuxt/kit (dev kit).

Getting Started

Initialize a project with the CLI:

npx nuxi@latest init nuxt-learn-examples

If the download fails, add a host entry:

185.199.108.133 raw.githubusercontent.com

The latest Nuxt 3.14 project uses app.vue as the entry point and omits pages and plugins directories by default.

Routing

Nuxt uses Vue‑Router under the hood. Adding a file under pages/ automatically creates a route. Example directory:

- pages
  - index.vue
  - about.vue
  - products
    - [id].vue

Generated route configuration:

{
  "routes": [
    { "path": "/index", "component": "pages/index.vue" },
    { "path": "/about", "component": "pages/about.vue" },
    { "path": "/products/:id", "component": "pages/products/[id].vue" }
  ]
}

Use <NuxtLink to="/about">About</NuxtLink> for navigation; Nuxt prefetches linked pages automatically.

SEO and Meta

Set head information via useSeoMeta or component tags ( <Title> , <Meta> , <Link> , etc.). Example:

<script setup lang="ts">
useSeoMeta({
  title: 'Taobei Shopping',
  description: 'A shopping site even better than Taobao.',
  ogImage: 'https://taobei.com/image.png'
})
</script>

Alternatively, use useHead to add <Title> , <Meta> , <Style> , and external resources.

Styling

Place CSS in assets/ and import it in components or via nuxt.config.ts . Example:

import '~/assets/css/first.css'
<style>@import url("~/assets/css/second.css");</style>

Global CSS can be added in nuxt.config.ts :

export default defineNuxtConfig({
  css: ['~/assets/css/main.css']
})

Data Fetching

Use useFetch , useAsyncData or the low‑level $fetch (alias of ofetch ) to retrieve data on both server and client. Example:

const { data, error, refresh } = await useFetch('/api/users')

Options such as server: false or lazy: true control where and when the request runs. Caching is automatic based on the request URL or an explicit key .

State Management

Nuxt provides useState for SSR‑compatible shared state, and integrates with Pinia, Harlem, XState, etc. Example of a global counter:

const counter = useState('counter', () => Math.round(Math.random()*1000))

Define reusable composables in composables/states.ts and import them anywhere.

Extending Nuxt with Modules

Nuxt’s module system lets you add plugins, components, routes, middleware, and more. There are already over 250 community modules. Create a new module with:

npx nuxi init -t module my-module
npm run dev:prepare

Define the module in src/module.ts using defineNuxtModule with meta , defaults , hooks , and a setup function that registers plugins, imports, and runtime code.

Conclusion

Nuxt brings Vue’s ecosystem to the server, offering out‑of‑the‑box SSR, file‑based routing, Pinia state management, and a rich module ecosystem, making it a low‑learning‑curve solution for developers familiar with Vue who need universal applications.

SSRFrontendDevelopmentNuxtServerSideRendering
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.