Skip to content

Commit 0c1a8d6

Browse files
authored
feat: NextJS rendering demo showcasing CSR, SSR, and SSG (#666)
Signed-off-by: Anthony D. Mays <[email protected]>
1 parent 47dca55 commit 0c1a8d6

File tree

17 files changed

+4086
-0
lines changed

17 files changed

+4086
-0
lines changed
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# Rendering Methods Demo
2+
3+
A comprehensive demonstration of three different rendering approaches in modern web development:
4+
5+
- **Client-Side Rendering (CSR)** - Dynamic data fetching in the browser
6+
- **Server-Side Rendering (SSR)** - HTML generated on each request
7+
- **Static Site Generation (SSG)** - Pre-built HTML at build time
8+
9+
## Features
10+
11+
### 🌐 CSR (Client-Side Rendering)
12+
- Demonstrates data fetching after page load
13+
- Shows loading states and error handling
14+
- Interactive refetch functionality
15+
- Real-time performance metrics
16+
17+
### ⚡️ SSR (Server-Side Rendering)
18+
- Server-side data fetching with `getServerSideProps`
19+
- Shows render timestamp for each request
20+
- SEO-friendly pre-populated content
21+
- Server performance metrics
22+
23+
### 🏗️ SSG (Static Site Generation)
24+
- Build-time data fetching with `getStaticProps`
25+
- Static HTML generation
26+
- Optional ISR (Incremental Static Regeneration)
27+
- Build timestamp tracking
28+
29+
### 💧 Hydration Error Demo
30+
- Demonstrates common hydration mismatches
31+
- Shows server vs client rendering differences
32+
- Browser console error examples
33+
- Best practices for preventing hydration issues
34+
35+
## Technology Stack
36+
37+
- **Framework**: Next.js 14
38+
- **Language**: TypeScript
39+
- **Styling**: Tailwind CSS
40+
- **Data Source**: JSONPlaceholder API
41+
- **Deployment**: Vercel-ready
42+
43+
## Getting Started
44+
45+
### Prerequisites
46+
- Node.js 18+
47+
- npm or yarn
48+
49+
### Installation
50+
51+
1. Clone or download this project
52+
2. Install dependencies:
53+
```bash
54+
npm install
55+
```
56+
57+
3. Run the development server:
58+
```bash
59+
npm run dev
60+
```
61+
62+
4. Open [http://localhost:3000](http://localhost:3000) in your browser
63+
64+
### Build for Production
65+
66+
```bash
67+
npm run build
68+
npm run start
69+
```
70+
71+
## Project Structure
72+
73+
```
74+
├── components/
75+
│ └── Layout.tsx # Shared layout component
76+
├── pages/
77+
│ ├── _app.tsx # Next.js app configuration
78+
│ ├── index.tsx # Home page with explanations
79+
│ ├── csr.tsx # Client-Side Rendering demo
80+
│ ├── ssr.tsx # Server-Side Rendering demo
81+
│ ├── ssg.tsx # Static Site Generation demo
82+
│ ├── ssg-error.tsx # SSG error handling demo
83+
│ └── hydration-error.tsx # Hydration mismatch demo
84+
├── styles/
85+
│ └── globals.css # Global styles and Tailwind
86+
└── README.md
87+
```
88+
89+
## Key Differences Demonstrated
90+
91+
### CSR (Client-Side Rendering)
92+
- ✅ Fast initial page load (minimal HTML)
93+
- ✅ Rich interactivity
94+
- ✅ Reduced server load
95+
- ❌ SEO challenges
96+
- ❌ Slower perceived performance
97+
- ❌ Loading states required
98+
99+
### SSR (Server-Side Rendering)
100+
- ✅ Excellent SEO
101+
- ✅ Fast perceived performance
102+
- ✅ Works without JavaScript
103+
- ❌ Higher server load
104+
- ❌ Slower page navigation
105+
- ❌ Complex caching
106+
107+
### SSG (Static Site Generation)
108+
- ✅ Fastest loading times
109+
- ✅ Perfect SEO
110+
- ✅ CDN-friendly
111+
- ✅ Lower hosting costs
112+
- ❌ Static content only
113+
- ❌ Rebuild required for updates
114+
- ❌ Longer build times
115+
116+
## Performance Comparison
117+
118+
Navigate between the three examples to observe:
119+
- **Load times**: SSG fastest, then SSR, then CSR
120+
- **Interactivity**: CSR most interactive, SSR/SSG less so
121+
- **SEO**: SSG/SSR excellent, CSR requires additional setup
122+
- **Caching**: SSG easiest to cache, SSR complex, CSR variable
123+
- **Hydration**: SSR/SSG can have hydration mismatches, CSR doesn't
124+
125+
## Use Cases
126+
127+
### When to use CSR:
128+
- Single Page Applications (SPAs)
129+
- Highly interactive dashboards
130+
- Applications requiring frequent updates
131+
- User-specific content
132+
133+
### When to use SSR:
134+
- E-commerce product pages
135+
- News websites
136+
- Dynamic content that needs SEO
137+
- Personalized content
138+
139+
### When to use SSG:
140+
- Marketing websites
141+
- Blogs and documentation
142+
- Landing pages
143+
- Content that changes infrequently
144+
145+
## API Used
146+
147+
This demo uses the [JSONPlaceholder](https://jsonplaceholder.typicode.com/) API for sample data:
148+
- Posts: `/posts`
149+
- Users: `/users`
150+
151+
## Deployment
152+
153+
This project is ready to deploy on Vercel:
154+
155+
1. Push to GitHub
156+
2. Connect to Vercel
157+
3. Deploy with default settings
158+
159+
Or deploy manually:
160+
```bash
161+
npm run build
162+
npm run start
163+
```
164+
165+
## Learning Resources
166+
167+
- [Next.js Documentation](https://nextjs.org/docs)
168+
- [React Documentation](https://react.dev)
169+
- [Tailwind CSS Documentation](https://tailwindcss.com/docs)
170+
171+
## License
172+
173+
MIT License - feel free to use this project for learning and demonstration purposes.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import React from 'react'
2+
import Link from 'next/link'
3+
import Head from 'next/head'
4+
5+
interface LayoutProps {
6+
children: React.ReactNode
7+
title?: string
8+
}
9+
10+
const Layout: React.FC<LayoutProps> = ({ children, title = 'Rendering Methods Demo' }) => {
11+
return (
12+
<>
13+
<Head>
14+
<title>{title}</title>
15+
<meta name="description" content="Demo showcasing CSR, SSR, and SSG rendering methods" />
16+
<meta name="viewport" content="width=device-width, initial-scale=1" />
17+
<link rel="icon" href="/favicon.ico" />
18+
</Head>
19+
20+
<div className="min-h-screen bg-gray-50">
21+
<nav className="bg-white shadow-sm border-b">
22+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
23+
<div className="flex justify-between items-center h-16">
24+
<div className="flex-shrink-0">
25+
<Link href="/" className="text-xl font-bold text-blue-600">
26+
Rendering Demo
27+
</Link>
28+
</div>
29+
<div className="hidden md:block">
30+
<div className="ml-10 flex items-baseline space-x-4">
31+
<Link href="/" className="nav-link">
32+
Home
33+
</Link>
34+
<Link href="/csr" className="nav-link">
35+
CSR
36+
</Link>
37+
<Link href="/ssr" className="nav-link">
38+
SSR
39+
</Link>
40+
<Link href="/ssg" className="nav-link">
41+
SSG
42+
</Link>
43+
<Link href="/hydration-error" className="nav-link">
44+
Hydration
45+
</Link>
46+
</div>
47+
</div>
48+
</div>
49+
</div>
50+
</nav>
51+
52+
<main className="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
53+
{children}
54+
</main>
55+
56+
<footer className="bg-white border-t mt-auto">
57+
<div className="max-w-7xl mx-auto py-4 px-4 sm:px-6 lg:px-8">
58+
<p className="text-center text-sm text-gray-500">
59+
Demo showcasing different rendering methods: CSR, SSR, and SSG
60+
</p>
61+
</div>
62+
</footer>
63+
</div>
64+
65+
<style jsx>{`
66+
.nav-link {
67+
@apply text-gray-500 hover:text-gray-900 px-3 py-2 rounded-md text-sm font-medium transition-colors;
68+
}
69+
.nav-link:hover {
70+
@apply bg-gray-100;
71+
}
72+
`}</style>
73+
</>
74+
)
75+
}
76+
77+
export default Layout
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/// <reference types="next" />
2+
/// <reference types="next/image-types/global" />
3+
4+
// NOTE: This file should not be edited
5+
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/** @type {import('next').NextConfig} */
2+
const nextConfig = {
3+
reactStrictMode: true,
4+
swcMinify: true,
5+
experimental: {
6+
appDir: false, // Using Pages Router for clearer demonstration
7+
},
8+
}
9+
10+
module.exports = nextConfig

0 commit comments

Comments
 (0)