Last updated: Apr 13, 2025
Table of Contents
1. What is Server-Side Rendering (SSR)?
Server-Side Rendering (SSR) is a technique where the content for a web page is generated on the server for each user request, rather than primarily in the user’s browser (Client-Side Rendering or CSR). When a user requests a page, the server fetches necessary data, renders the complete HTML page, and sends it directly to the browser.
1.1 Why Use SSR?
SSR offers several key advantages over traditional CSR Single Page Applications (SPAs):
-
Improved SEO:Search engine crawlers can easily index the content because the fully rendered HTML is available immediately, without needing to execute JavaScript.
-
Faster First Contentful Paint (FCP):Users see meaningful content sooner because the browser receives renderable HTML instead of a blank page and JavaScript bundles. This improves perceived performance.
-
Better Social Sharing:Platforms like Twitter or Facebook can pull metadata (titles, descriptions, images) directly from the server-rendered HTML for rich previews.
-
Consistent Performance:Less reliance on the user’s device capabilities, as the heavy lifting of initial rendering happens on the server.
1.2 How SSR Works
The basic flow of an SSR request is:
User requests a page URL.
The server receives the request and identifies the corresponding page component.
The server executes code (often specific data-fetching functions) to get the data needed for that page.
The server renders the page component with the fetched data into an HTML string.
The server sends the complete HTML document to the user’s browser.
The browser displays the HTML. JavaScript bundles are then downloaded and executed to “hydrate” the static HTML, making it interactive (attaching event listeners, etc.).
Frameworks like Next.js and Nuxt.js abstract much of this complexity away.
2. Introduction to Next.js (React)
Next.js is a popular open-source framework built on top of React. Developed by Vercel, it provides conventions and tooling for building React applications with various rendering strategies, including SSR, Static Site Generation (SSG), and Incremental Static Regeneration (ISR).
2.1 Core Concepts
-
React-Based:Leverages the React library for building user interfaces.
-
File-System Routing:Creates routes automatically based on the file structure within thepagesdirectory (orappdirectory in newer versions).
-
Hybrid Rendering:Allows pages to be rendered using different strategies (SSR, SSG, ISR, CSR) on a per-page basis.
-
API Routes:Easily create serverless API endpoints within thepages/api(orapp/api) directory.
-
Built-in Optimizations:Includes features like image optimization, code splitting, and prefetching.
2.2 SSR Implementation
In the traditional Next.js Pages Router, SSR is primarily achieved using the getServerSideProps function exported from a page file. This function runs on the server for every request.
// pages/posts/[id].js (Pages Router example)
import React from 'react';
function PostPage({ post }) {
// Render post data...
return (
<div>
<h1>{post.title}</h1>
<p>{post.body}</p>
</div>
);
}
export async function getServerSideProps(context) {
// Runs on every request on the server
const { id } = context.params; // Get post ID from route params
const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`);
const post = await res.json();
if (!post) {
return { notFound: true }; // Handle case where post doesn't exist
}
// Data returned in props will be passed to the page component
return {
props: {
post,
},
};
}
export default PostPage;
In the newer Next.js App Router, server components fetch data directly using async/await, and client components can use hooks like useEffect or libraries like SWR/React Query for data fetching, with SSR often being the default for server components.
3. Introduction to Nuxt.js (Vue)
Nuxt.js is a framework inspired by Next.js but built for the Vue.js ecosystem. It provides a streamlined development experience for building universal (SSR), static, and single-page Vue applications.
3.1 Core Concepts
-
Vue-Based:Built on top of Vue.js, leveraging its component model and reactivity system.
-
File-System Routing:Like Next.js, automatically generates routes based on thepagesdirectory structure.
-
Rendering Modes:Supports Universal (SSR), Static (SSG), and SPA modes.
-
Nitro Server Engine (Nuxt 3):A powerful server engine offering features like API routes (server/api), server middleware (server/middleware), and deployment presets for various platforms.
-
Auto Imports:Automatically imports components, composables, and utils.
-
Module Ecosystem:Extensible via a rich ecosystem of Nuxt modules.
3.2 SSR Implementation
Nuxt 3 (the current version) simplifies SSR data fetching primarily through composables like useFetch and useAsyncData used within <script setup>. These composables work universally – they run on the server during the initial request and can also run on the client during navigation.
<!-- pages/posts/[id].vue (Nuxt 3 example) -->
<script setup>
import { useRoute } from 'vue-router';
const route = useRoute();
const postId = route.params.id;
// useFetch runs on server for initial load, client for navigation
// It automatically handles fetching, state management, and error handling.
const { data: post, pending, error } = await useFetch(
`https://jsonplaceholder.typicode.com/posts/${postId}`,
{
// Optional: key ensures fetch is unique if params change
key: `post-${postId}`,
// Optional: pick only needed fields
// pick: ['title', 'body']
}
);
// Handle loading state
if (pending.value) {
console.log('Loading post...');
}
// Handle error state
if (error.value) {
console.error('Error fetching post:', error.value);
// Optionally show an error page or message
// throw createError({ statusCode: 404, statusMessage: 'Post Not Found' });
}
// Nuxt 2 used `asyncData` or `Workspace` hooks in the Options API for SSR data.
// Nuxt 3's composable approach is generally preferred now.
</script>
<template>
<div>
<p v-if="pending">Loading...</p>
<div v-else-if="post">
<h1></h1>
<p></p>
</div>
<p v-else-if="error">Could not load post. Error: </p>
</div>
</template>
useAsyncData provides more control, allowing you to provide your own async function for fetching.
4. Feature Comparison: Next.js vs. Nuxt.js for SSR
4.1 Data Fetching
-
Next.js:Primarily usesgetServerSideProps(Pages Router) for per-request server-side data or directasync/awaitin Server Components (App Router). Requires explicit handling of data fetching logic.
-
Nuxt.js (v3):Uses composables likeuseFetch/useAsyncDatawithin