Most SaaS founders hit the same wall. The product is almost ready but the landing page is not. So they spend two weeks in Webflow, or $3,000 on a designer, or they ship with a placeholder that quietly loses half the visitors who would have converted.
You do not have to do any of that. If you are building on a Next.js SaaS boilerplate, you already have Tailwind CSS, Shadcn UI components, and server components that render instantly. You are closer to a finished landing page than you think.
This post walks through the five sections every SaaS landing page needs, what to put in each one, and how to build them without a page builder or a separate marketing site.
Most landing pages fail not because they are ugly but because they are built in the wrong order. Founders start with the feature list and never get to the part the visitor actually cares about -- whether this solves their problem.
Here is the order that works:
That is it. Founders add FAQ sections, animated demos, and enterprise logo bars before anyone has signed up. Ship the five sections first.
The hero has one job: answer "what is this and should I keep reading?" in under five seconds.
Your headline should name the outcome, not the product. "Launch your SaaS idea in a weekend" beats "A modern Next.js boilerplate." Your subheadline can add one detail -- who it is for, or what makes it different.
In Next.js, the hero is a server component. No state, no client bundle, and the content renders on the first byte. A primary button from your Shadcn UI components and a screenshot of your product is all you need to start:
// components/landing/HeroSection.tsx
import { Button } from "@/components/ui/button";
import Link from "next/link";
export function HeroSection() {
return (
<section className="flex flex-col items-center text-center py-24 gap-6">
<h1 className="text-5xl font-bold tracking-tight max-w-2xl">
Launch your SaaS idea in a weekend
</h1>
<p className="text-xl text-muted-foreground max-w-xl">
Auth, payments, email, and database -- already wired up. You build
the feature that makes your product unique.
</p>
<Link href="/register">
<Button size="lg">Get started free</Button>
</Link>
</section>
);
}
No external library needed. The text-muted-foreground class adapts to dark and light mode automatically because it resolves to a CSS variable -- the same system your whole app already uses.
You probably already have Stripe subscriptions set up. The SaaS pricing page post covers how to build a pricing section with a monthly/annual toggle -- drop that component directly into your landing page.
If you want something simpler first, three Card components from Shadcn UI with a highlighted "Recommended" badge on the middle plan is enough to ship. The visual pattern is proven and visitors recognize it immediately.
One rule: always show a price. "Contact us for pricing" on a landing page without an established brand kills conversions. Even a starting-from number is better than a question mark.
Visitors want to know two things: will this actually work for me, and how hard is it? Three steps with concrete outcomes answer both.
The outcome of each step should be something the reader can picture. "Set up authentication" is abstract. "Users can register and log in -- 30 minutes" is a picture. Use icons from Lucide React (already in your project) and keep each step to one sentence.
You do not need a wall of logos. One strong signal works better than ten weak ones.
Options ranked by what you probably have access to right now:
If you have nothing yet, lead with the founder's photo and a one-sentence story. "I built this because I was rebuilding auth for the fourth time and decided to stop" is more credible than a generic trust badge.
Your page file composes named components in the order that converts:
// app/(main)/page.tsx
import { HeroSection } from "@/components/landing/HeroSection";
import { SocialProofSection } from "@/components/landing/SocialProofSection";
import { HowItWorksSection } from "@/components/landing/HowItWorksSection";
import { PricingSection } from "@/components/landing/PricingSection";
import { CtaSection } from "@/components/landing/CtaSection";
export default function HomePage() {
return (
<>
<HeroSection />
<SocialProofSection />
<HowItWorksSection />
<PricingSection />
<CtaSection />
</>
);
}
Each section lives in components/landing/ as its own server component. Your SEO metadata -- title, description, OG image -- goes in the metadata export at the top of the page file. The SEO setup post covers the exact pattern so every section is discoverable from Google on day one.
A page builder is faster for the first hour and slower for everything after. You cannot wire a Webflow form directly to your Drizzle ORM waitlist table without a third-party integration. You cannot show a logged-in user a personalized CTA. You cannot run an A/B test without a paid plan on the builder.
When your landing page lives in the same codebase as your app, you can do all of that. The Shadcn UI components you already use in your dashboard are the same ones on your marketing page -- same design system, same dark mode support, zero inconsistency between the page that sells the product and the product itself.
The cost is that you write the layout yourself. With server components and a Tailwind foundation, a working five-section landing page is a day of work, not a week.
Get the Next.js SaaS boilerplate and ship your landing page this weekend.