You do not need three days to build a landing page. With Next.js App Router, Tailwind CSS v4, and a library of pre-built sections, you can go from npx create-next-app to a deployed, production-quality page in under an hour. This guide walks through the entire process — project setup, section assembly, and deployment.
Project Setup
Start with the latest Next.js and Tailwind CSS v4:
npx create-next-app@latest my-landing --app --ts --tailwind --src-dir
cd my-landing
This scaffolds a project with App Router, TypeScript, Tailwind, and a src/ directory. Next.js 15 uses Tailwind v4 by default, which means CSS-first configuration — no tailwind.config.ts needed for most setups.
Install Framer Motion for section animations:
npm install motion
Your project structure looks like this:
my-landing/
├── src/
│ ├── app/
│ │ ├── layout.tsx
│ │ └── page.tsx
│ └── components/
│ └── sections/
├── public/
├── package.json
└── tsconfig.json
Create a src/components/sections/ directory — each section lives here as its own file.
Section-by-Section Assembly
A high-converting landing page follows a proven formula. Here is the exact section order we will build, and why each section exists:
1. Hero Section
The hero states the value proposition in under 5 seconds. It needs a headline, a subtitle, a primary CTA button, and optionally a visual (screenshot, illustration, or gradient background).
// src/components/sections/Hero.tsx
"use client";
import { motion } from "motion/react";
const ease = [0.16, 1, 0.3, 1] as const;
export function Hero() {
return (
<section className="flex min-h-[80vh] flex-col items-center justify-center px-4 text-center">
<motion.h1
initial={{ opacity: 0, y: 32 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.7, ease }}
className="max-w-3xl text-5xl font-bold tracking-tight md:text-6xl"
>
Build landing pages at the speed of thought
</motion.h1>
<motion.p
initial={{ opacity: 0, y: 24 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.7, ease, delay: 0.1 }}
className="mt-6 max-w-xl text-lg text-muted-foreground"
>
844+ production-ready React sections. Copy, paste, ship.
</motion.p>
<motion.div
initial={{ opacity: 0, y: 16 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.7, ease, delay: 0.2 }}
className="mt-8 flex gap-4"
>
<a href="#pricing" className="rounded-xl bg-primary px-6 py-3 font-semibold text-primary-foreground">
Get started
</a>
<a href="#features" className="rounded-xl border border-border px-6 py-3 font-semibold">
See features
</a>
</motion.div>
</section>
);
}
Browse more hero variants for split layouts, video backgrounds, and gradient styles.
2. Logo Carousel
Immediately after the hero, show logos of companies or integrations. This establishes trust before the visitor evaluates your features. A simple marquee animation works:
// src/components/sections/LogoCarousel.tsx
export function LogoCarousel({ logos }: { logos: { src: string; alt: string }[] }) {
return (
<section className="overflow-hidden border-y border-border py-8">
<div className="flex animate-marquee gap-12">
{[...logos, ...logos].map((logo, i) => (
<img key={i} src={logo.src} alt={logo.alt} className="h-8 opacity-50 grayscale" />
))}
</div>
</section>
);
}
Add the marquee keyframe to your global CSS:
@keyframes marquee {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
}
.animate-marquee {
animation: marquee 30s linear infinite;
}
3. Features Grid
Show how your product delivers on the hero's promise. A 3-column grid with icon, title, and description is the standard:
// src/components/sections/Features.tsx
"use client";
import { motion } from "motion/react";
interface Feature {
icon: React.ReactNode;
title: string;
description: string;
}
const stagger = {
hidden: {},
visible: { transition: { staggerChildren: 0.08 } },
};
const item = {
hidden: { opacity: 0, y: 20 },
visible: { opacity: 1, y: 0, transition: { duration: 0.5 } },
};
export function Features({ features }: { features: Feature[] }) {
return (
<section id="features" className="mx-auto max-w-6xl px-4 py-24">
<h2 className="text-center text-3xl font-bold">Everything you need</h2>
<motion.div
variants={stagger}
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: "-80px" }}
className="mt-12 grid gap-8 md:grid-cols-2 lg:grid-cols-3"
>
{features.map((f) => (
<motion.div key={f.title} variants={item} className="rounded-2xl border border-border p-6">
<div className="mb-4 text-2xl">{f.icon}</div>
<h3 className="text-lg font-semibold">{f.title}</h3>
<p className="mt-2 text-sm text-muted-foreground">{f.description}</p>
</motion.div>
))}
</motion.div>
</section>
);
}
See the full range of feature section layouts — alternating rows, bento grids, icon grids, and more.
4. Testimonials
Social proof from real users. Three testimonial cards in a row is the simplest effective layout:
// src/components/sections/Testimonials.tsx
interface Testimonial {
quote: string;
name: string;
role: string;
avatar: string;
}
export function Testimonials({ testimonials }: { testimonials: Testimonial[] }) {
return (
<section id="social-proof" className="bg-muted/50 px-4 py-24">
<h2 className="text-center text-3xl font-bold">Loved by developers</h2>
<div className="mx-auto mt-12 grid max-w-5xl gap-8 md:grid-cols-3">
{testimonials.map((t) => (
<div key={t.name} className="rounded-2xl border border-border bg-card p-6">
<p className="text-sm italic text-muted-foreground">“{t.quote}”</p>
<div className="mt-4 flex items-center gap-3">
<img src={t.avatar} alt={t.name} className="h-10 w-10 rounded-full" />
<div>
<p className="text-sm font-semibold">{t.name}</p>
<p className="text-xs text-muted-foreground">{t.role}</p>
</div>
</div>
</div>
))}
</div>
</section>
);
}
Explore testimonial variants for marquee, masonry, and video testimonial layouts.
5. Pricing
Remove the "how much?" objection. A toggle between monthly and annual pricing is the standard SaaS pattern. Check the pricing section catalog for toggle, tier-comparison, and calculator layouts.
6. CTA + Footer
Close with a clear call to action and a minimal footer. The CTA restates the value proposition and offers one button. The footer provides legal links, social links, and a copyright notice.
Composing the Page
Wire all sections together in src/app/page.tsx:
import { Hero } from "@/components/sections/Hero";
import { LogoCarousel } from "@/components/sections/LogoCarousel";
import { Features } from "@/components/sections/Features";
import { Testimonials } from "@/components/sections/Testimonials";
export default function HomePage() {
return (
<main>
<Hero />
<LogoCarousel logos={[/* your logos */]} />
<Features features={[/* your features */]} />
<Testimonials testimonials={[/* your testimonials */]} />
{/* Pricing */}
{/* CTA */}
{/* Footer */}
</main>
);
}
Each section is a standalone component with its own data contract. Replace mock data with real content and the page is production-ready.
Deployment
Vercel is the fastest path from code to URL for Next.js projects:
npx vercel --prod
Or connect your Git repository to Vercel for automatic deployments on every push. The build step detects Next.js automatically — no configuration needed.
For other platforms, next build && next start produces a production Node.js server. Export as static with output: "export" in next.config.ts if your landing page has no dynamic routes.
Faster Assembly with Incubator
Writing each section from scratch is the slow path. The Incubator catalog gives you 844+ production-ready React sections — heroes, feature grids, pricing tables, testimonials, CTAs, footers, navbars, and more. Each section is a self-contained component with mock data included. Browse the catalog, copy the sections you need, replace the content, deploy. That is how you ship a landing page in one hour.