Landing page
Hero, features, CTA — the standard parts.
The landing page is the first thing a customer sees. Three sections, a clear value prop, a CTA. This lesson is about shipping a respectable landing page in 30 minutes — not perfecting it.
The standard parts
- Hero — headline, sub-headline, primary CTA
- Social proof — logos, testimonials, stats
- Features grid — three to six benefit-led items
- Pricing / final CTA
- Footer — links, social, copyright
The hero — server component, no JS needed
import Link from 'next/link'export default function HomePage() {return (<><section className="py-24 text-center"><h1 className="text-5xl font-bold tracking-tight max-w-2xl mx-auto">Run your retail business from one place</h1><p className="mt-4 text-lg text-muted-foreground max-w-xl mx-auto">POS, inventory, reports — built for shops with 1 to 50 outlets.</p><div className="mt-8 flex justify-center gap-3"><Link href="/signup" className="rounded-full bg-primary px-6 py-2.5 text-primary-foreground">Start free trial</Link><Link href="/demo" className="rounded-full border px-6 py-2.5">See a demo</Link></div></section><FeaturesGrid /><SocialProof /><FinalCTA /></>)}
Server component by default. No "use client" at the top. HTML ships pre-rendered; bundle stays tiny.
The features grid
function FeaturesGrid() {return (<section className="py-20 grid grid-cols-1 md:grid-cols-3 gap-8">{FEATURES.map((f) => (<div key={f.title} className="rounded-xl border p-6"><f.icon className="h-6 w-6 text-primary" /><h3 className="mt-3 text-lg font-semibold">{f.title}</h3><p className="mt-1 text-muted-foreground">{f.body}</p></div>))}</section>)}const FEATURES = [{ icon: Zap, title: 'POS in 5 seconds', body: 'Scan, total, print receipt. No training needed.' },{ icon: Box, title: 'Inventory that just works', body: 'Re-order alerts, multi-location, batch tracking.' },{ icon: BarChart, title: 'Reports out of the box', body: 'Daily, weekly, year-over-year. Export to Excel.' },]
Why server components win for landing pages
- No hydration cost. The user gets HTML; the JS bundle is minimal. Lighthouse loves it.
- SEO-friendly out of the box. Bots see the content directly.
- Can fetch at request time. Stats, latest testimonials — fetch in a server component, render to HTML.
<Link>, the dark-mode toggle a small client component. The page stays mostly static.Reusable hero pattern
Pull the hero into components/hero.tsx so other marketing pages (about, pricing, blog index) can reuse it. Pass { title, subtitle, ctaHref, ctaText } as props.
Quick check
Try it
Build a real landing page on your scaffolded project:
- Replace
apps/web/app/(marketing)/page.tsxwith hero + features grid + final CTA. - Add at least three feature items, real product-y copy.
- Open
localhost:3000— verify it looks like a product page, not a default Next template. - Run Lighthouse on it (Chrome DevTools → Lighthouse → Performance). Aim for ≥90.
Paste your Lighthouse score in notes.md.
What's next
Last lesson of this chapter — SEO + Open Graph. Make your page discoverable and shareable.
Spot a typo? Have an idea?
Help us improve this lesson. One click opens a GitHub issue with the lesson URL pre-filled — suggest clearer wording, report a bug, or request more depth. The course keeps improving thanks to learners like you.
Suggest an improvement on GitHub