Table of Contents


How to Implement Server-Side Rendering (SSR) in a Next.js

Next.js introduces powerful enhancements for building modern web applications with improved performance, scalability, and SEO. In this guide, we’ll demonstrate how to implement Server-Side Rendering (SSR) using the App Router, create dynamic pages, and add SEO metadata with generateMetadata().

Step 1: Initialize a Next.js 14 App with App Router

Use the official Next.js CLI to bootstrap your project:


npx create-next-app@14							
							

Follow the CLI prompts to configure your project. Ensure that App Router is selected (it uses the app/ directory by default).

Navigate into your project directory:


cd my-ssr-app							
							

Step 2: Run the Development Server

Start your application:


npm run dev					
							

Visit http://localhost:3000 to see the default landing page.

Step 3: Project Structure Overview

Your initial folder structure with App Router will look like:

Step 4: Create a Server-Side Rendered Page

Let’s fetch and render data during the server render phase using native SSR capabilities of App Router.

app/page.tsx:


async function getPosts() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts', {
    cache: 'no-store',
  });
  return res.json();
}

export default async function PostsPage() {
  const posts = await getPosts();

  return (
    <div className="p-6">
      <h1 className="text-2xl font-bold mb-4">SSR Posts</h1>
      <ul className="space-y-2">
        {posts.slice(0, 5).map((post: any) => (
          <li key={post.id} className="border p-4 rounded shadow">
            <h2 className="font-semibold">{post.title}</h2>
            <p>{post.body}</p>
          </li>
        ))}
      </ul>
    </div>
  );
}			
							

Note: cache: 'no-store' ensures the page is server-rendered on every request enabling pure SSR.

Understanding SSR in App Router

In Next.js 14:

All components inside the app/ directory are Server Components by default.

Using fetch() directly inside a Server Component allows data fetching during server render.

Secrets and server-only logic are safe in Server Components.

To enable client-side interactivity, prepend 'use client' at the top of the component.

Now, open your browser and visit

http://localhost:3000/ — you should see the server-side rendered list of posts.

Step 5 :Add Static Pages with Dynamic SEO Metadata

To make your app SEO-friendly, add separate static pages with unique metadata. Next.js 14 supports generateMetadata() for setting SEO metadata dynamically at the file level.

Now we will add two new pages called about and services, here’s how the updated project structure appears:

app/about/page.tsx


async function getAboutData() {
  const res = await fetch("https://jsonplaceholder.typicode.com/posts/1", {
    cache: "no-store",
  });
  return res.json();
}

export async function generateMetadata() {
  const data = await getAboutData();
  return {
    title: `About Us - ${data.title}`,
    description: data.body,
    keywords: ['about us', 'company info', 'team'],
  };
}

export default async function AboutPage() {
  const data = await getAboutData();

  return (
    <main className="p-6">
      <h1 className="text-2xl font-bold mb-4">About Us</h1>
      <p className="text-gray-700">{data.body}</p>
    </main>
  );
}									
									

Step 6: About Page Preview with SEO Metadata

Look at the http://localhost:3000/about tab , it shows the title "About Us - sunt aut facere repellat provident", which comes directly from the dynamic SEO metadata we defined in the page file.

Here is

app/services/page.tsx


async function getServicesData() {
  const res = await fetch("https://jsonplaceholder.typicode.com/posts/2", {
    cache: "no-store",
  });
  return res.json();
}

export async function generateMetadata() {
  const data = await getServicesData();
  return {
    title: `Our Services - ${data.title}`,
    description: data.body,
    keywords: ['services', 'solutions', 'offerings'],
  };
}

export default async function ServicesPage() {
  const data = await getServicesData();

  return (
    <main className="p-6">
      <h1 className="text-2xl font-bold mb-4">Our Services</h1>
      <p className="text-gray-700">{data.body}</p>
    </main>
  );
}									
									

Step 7: Services Page Preview with SEO Metadata

Look at the http://localhost:3000/services tab, it shows the title "Services - qui est esse", which comes directly from the dynamic SEO metadata we defined in the page file

Benefits of SSR with Dynamic Metadata

By combining Server-Side Rendering with dynamic SEO metadata, your application:

Renders content on the server, delivering HTML to crawlers and clients faster.

Ensures search engines index meaningful content, even before JavaScript loads.

Enables per-page metadata (title, description, keywords), improving click-through rates (CTR).

Final Thoughts

With Next.js 14 and the App Router:

SSR is seamless and default for Server Components.

fetch() inside components ensures data is available before page load.

generateMetadata() makes it easy to enhance SEO on a per-page basis.

This architecture results in a blazing-fast, SEO-friendly blog or web application out-of-the-box — perfect for modern web development.

Ready to Build Something Amazing?

Get in touch with Prishusoft – your trusted partner for custom software development. Whether you need a powerful web application or a sleek mobile app, our expert team is here to turn your ideas into reality.

image