← Home/Blog/How I Build a Landing Page from Zero to Live in One Day
Productivity#nextjs#landing-page#ui#hosting

How I Build a Landing Page from Zero to Live in One Day

The real stack I use to ship landing pages fast: Next.js + shadcn/ui + Vercel. From setup to deploy, with a list of UI tools and hosting options I actually trust.

CP

CHAEI PUEI Tech

8 min read

Background

I constantly need to build landing pages fast — for side projects, small clients, or testing an MVP. After trying a bunch of different approaches, I settled on a stack that lets me go from idea to live URL in a single workday.

This post walks through exactly that process.

My Stack

LayerToolWhy
FrameworkNext.js 16 App RouterServer Components, zero-config deploy
UI Componentsshadcn/uiAccessible, customizable, own code
StylingTailwind CSS v4Utility-first, fast
HostingVercelFastest deploy for Next.js
AnalyticsPlausibleLightweight, no cookies
Design refFigma (Free plan)Quick wireframing

Step 1: Project Setup (15 minutes)

💻bash
# Create Next.js project
npx create-next-app@latest my-landing --typescript --tailwind --app

# Enter the directory
cd my-landing

# Init shadcn/ui
npx shadcn@latest init

# Add commonly used components
npx shadcn@latest add button card badge separator

When initializing shadcn, pick:

Step 2: Layout Structure (30 minutes)

A solid landing page is made up of these sections:

💻tsx
// app/page.tsx
export default function Home() {
  return (
    <main>
      <Navbar />       {/* Logo + nav links + CTA button */}
      <Hero />         {/* Headline + subtext + primary CTA */}
      <SocialProof />  {/* Logos, testimonials, số liệu */}
      <Features />     {/* 3-6 tính năng chính */}
      <Pricing />      {/* Bảng giá */}
      <FAQ />          {/* Câu hỏi thường gặp */}
      <CTA />          {/* Final call to action */}
      <Footer />       {/* Links + copyright */}
    </main>
  );
}

Each section is its own Server Component — easy to maintain, easy to reorder.

Step 3: Hero Section with shadcn/ui

💻tsx
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";

export function Hero() {
  return (
    <section className="py-20 px-4 text-center max-w-4xl mx-auto">
      <Badge variant="secondary" className="mb-4">
        🚀 Mới ra mắt
      </Badge>

      <h1 className="text-4xl sm:text-6xl font-bold tracking-tight mb-6">
        Làm sản phẩm
        <span className="text-primary"> nhanh hơn</span>
      </h1>

      <p className="text-xl text-muted-foreground mb-8 max-w-2xl mx-auto">
        Mô tả ngắn gọn giá trị sản phẩm mang lại. Tập trung vào
        outcome, không phải features.
      </p>

      <div className="flex gap-3 justify-center flex-wrap">
        <Button size="lg" asChild>
          <a href="#pricing">Bắt đầu miễn phí</a>
        </Button>
        <Button size="lg" variant="outline" asChild>
          <a href="#features">Xem demo →</a>
        </Button>
      </div>
    </section>
  );
}

💡 A great headline = [Target user] uses [Product] to [achieve outcome] without [pain point].

Step 4: Typography with Inter

Inter is the go-to font for landing pages — readable, professional, and free:

💻tsx
// app/layout.tsx
import { Inter } from "next/font/google";

const inter = Inter({
  subsets: ["latin"],
  display: "swap",
  variable: "--font-inter",
});

export default function RootLayout({ children }) {
  return (
    <html lang="vi" className={inter.variable}>
      <body className="font-sans antialiased">{children}</body>
    </html>
  );
}

Step 5: Deploy to Vercel (5 minutes)

💻bash
# Push to GitHub
git init && git add . && git commit -m "Initial landing page"
git remote add origin git@github.com:username/repo.git
git push -u origin main

Then:

  1. Go to vercel.com → New Project
  2. Import your GitHub repo
  3. Click Deploy

Vercel auto-detects Next.js, configures the build, and deploys in 30 seconds.

ℹ️ The free Hobby plan supports custom domains, automatic SSL, and unlimited Git deploys.

Step 6: Add Analytics (10 minutes)

Once it's live, you'll want to know who's visiting:

💻tsx
// app/layout.tsx — add Plausible
import Script from "next/script";

// Inside <body>:
<Script
  defer
  data-domain="yourdomain.com"
  src="https://plausible.io/js/script.js"
/>

Plausible is 45× lighter than Google Analytics, and no cookie banner required.

Pre-launch Checklist

Real-world Timeline

With this stack, a typical day looks like:

Total: 6 hours from idea to a production-ready live URL.

Resources

Found this useful?

Subscribe to get the latest technical articles and reviews from CHAEI PUEI Tech.

Subscribe for free