2

Server-Side Rendering (SSR)

Render fresh content on every request for dynamic, personalised data

Beginner

What It Does

  • Forces Server-Side Rendering
    The page will be rendered on the server for each request, never cached or pre-rendered at build time.
  • Disables Static Generation
    Even if Next.js could potentially optimise this page as static, this directive prevents caching.
  • Always Fresh Data
    Ensures the page always fetches the latest data from the server/database on each visit.

Why We Use It

  • User-Specific Content
    Middleware and auth helpers check login state before rendering if user is logged in, hence user-specific content can't be pre-rendered
  • personalised Content
    Page fetches user-specific dashboard data, and because each user sees different content based on their account
  • Real-time Data
    Account information needs to be current (courses, progress, settings) and hence can't use stale cached data
  • Security
    User data should never be cached or pre-rendered for security reasons, ensuring each user only sees their own data with real-time authentication checks

How it works

  1. 1
    User makes a request

    User visits /dashboard or their profile page

  2. 2
    Server checks authentication

    Middleware validates user session/token

  3. 3
    Fetch user-specific data

    Query database for that user's data

  4. 4
    Render page on server

    Generate personalised HTML

  5. 5
    Send to browser

    User receives fresh, personalised content

Code

// app/dashboard/page.tsx

// Force server-side rendering for every request
export const dynamic = 'force-dynamic'

export default async function DashboardPage() {
  // This code runs on the server for EVERY request
  const session = await getServerSession()
  
  if (!session) {
    redirect('/login')
  }
  
  // Fetch fresh user-specific data
  const userData = await fetch(
    `https://api.example.com/users/${session.user.id}/dashboard`,
    { cache: 'no-store' } // Never cache this data
  ).then(res => res.json())
  
  return (
    <div>
      <h1>Welcome back, {session.user.name}!</h1>
      
      <div>
        <h2>Your Courses</h2>
        {userData.courses.map(course => (
          <CourseCard key={course.id} course={course} />
        ))}
      </div>
      
      <div>
        <h2>Your Progress</h2>
        <ProgressChart data={userData.progress} />
      </div>
    </div>
  )
}