npx create-next-app@latest \
pixelcraft-web \
--typescript \
--tailwind \
--app
// app/gallery/page.tsx
// Server Component — runs on server
import { ImageGrid }
from '@/components/ImageGrid';
async function getPublicImages() {
const res = await fetch(
`${process.env.API_URL}` +
`/api/images/public`, {
next: { revalidate: 60 },
// ↑ Regenerate every 60 seconds
});
return res.json();
}
export default async function
GalleryPage() {
const images =
await getPublicImages();
return (
<main className="max-w-7xl
mx-auto px-4 py-8">
<h1 className="text-3xl
font-bold mb-8">
Public Gallery
</h1>
<ImageGrid images={images} />
</main>
);
}
// SEO metadata
export const metadata = {
title: 'PixelCraft Gallery' +
' — Community Creations',
description:
'Explore images edited with' +
' PixelCraft...',
openGraph: {
images: ['/og-gallery.jpg']
},
};
// app/page.tsx
// Static — generated at build time
export default function LandingPage() {
return (
<main>
<section className="h-screen
flex items-center
justify-center">
<div className="text-center">
<h1 className="text-6xl
font-bold">
PixelCraft
</h1>
<p className="text-xl
text-slate-400 mt-4">
Professional image editing
in your browser
</p>
<a href="/editor"
className="mt-8 inline-block
bg-cyan-600 px-8 py-3
rounded-lg">
Start Editing — Free
</a>
</div>
</section>
</main>
);
}
// No data fetching = static page.
// Built once at deploy time.
// Served from CDN. Instant load.
// Right-click → View Page Source
// ❌ SPA (before):
<html>
<body>
<div id="root"></div>
<script src="/bundle.js"></script>
</body>
</html>
// Google sees: nothing.
// ✅ Next.js SSR (after):
<html>
<body>
<main>
<h1>Public Gallery</h1>
<div class="grid">
<img src="..." alt="Sunset" />
<img src="..." alt="Portrait" />
...500 more images rendered...
</div>
</main>
</body>
</html>
// Google sees: everything.
git switch -c feature/PIXELCRAFT-087-nextjs-ssr
git add pixelcraft-web/
git commit -m "Add Next.js SSR gallery + landing page (PIXELCRAFT-087)"
git push origin feature/PIXELCRAFT-087-nextjs-ssr
# PR → Review → Merge → Close ticket ✅
The rendering spectrum: every strategy is a tradeoff.
Next.js lets you mix all four strategies in one application — different pages use different strategies based on their needs.