# Claude Code Landing Page That Does Not Look AI-Made

> Build a Claude Code landing page from real sections: connect them through MCP, set tokens and a rules file, then prompt one section at a time and check it.

- Author: [Serban Rusu](https://wingo-ui.com/blog/authors/serban), Founder of Wingo UI
- Published: Nov 5, 2026
- Category: [Building UI with AI agents](https://wingo-ui.com/blog/category/ai-agents)
- Reading time: 11 min
- Canonical: https://wingo-ui.com/blog/claude-code-landing-page

## TL;DR

A Claude Code landing page stops looking AI-made when the agent assembles real, tested sections instead of inventing markup, works inside your color tokens, and follows a short rules file that bans invented numbers, logos and quotes. Connect a component library through MCP, set the brand tokens and provider defaults once, then prompt one section at a time with the copy, the component and the check you expect. Finish by looking at the page at 390px and 1440px in both themes.

You asked Claude Code for a landing page and got the one everybody gets: a gradient headline, three cards with icons, "Trusted by 10,000+ teams" for a product with no users yet, and a testimonial from a person who does not exist. A Claude Code landing page looks AI-made when the agent has to invent everything. Give it real sections, your tokens and a rules file, and the same agent produces a page that looks like your product.

This tutorial builds the home page of a small invoicing app in Next.js with that setup. The sections come from Wingo UI ([Hero Section](https://wingo-ui.com/components/hero-section), [Pricing Section](https://wingo-ui.com/components/pricing-section), [FAQ Section](https://wingo-ui.com/components/faq-section) and [CTA Section](https://wingo-ui.com/components/cta-section)), but the order of work applies to any library with an MCP server. More on agents and UI is in [Building UI with AI agents](https://wingo-ui.com/blog/category/ai-agents).

## Why does a Claude Code landing page look AI-made?

Every decision the prompt leaves open gets the most common answer. A centered hero over a purple glow is common. So are three feature cards, a logo strip, a customer count and three quotes. None of these is wrong on its own. Together, with nothing from your product in them, they are the look people now recognize.

Two published approaches make the same trade. The landing-page skill in [jezweb/claude-skills](https://claudemarketplaces.com/skills/jezweb/claude-skills/landing-page) (last updated August 21, 2026) writes one HTML file with Tailwind loaded from a CDN, and the [GemPages tutorial](https://gempages.net/blogs/shopify/build-landing-page-with-claude-code) (updated June 8, 2026) asks for "clean semantic HTML with embedded CSS". That is a fine way to get a one-off page. It is not how you want the home page of a Next.js app built, where the page should share components, tokens and dark mode with everything else.

The worst tell is invented proof. A model asked for social proof writes social proof, with numbers. That is a design problem and a trust problem, and the fix belongs in the rules file, which every session reads, instead of in one prompt.

## What do you set up before the first prompt?

Four things, each of which removes a group of decisions from the model:

| Piece | Decisions it removes | How you add it |
| --- | --- | --- |
| MCP server | Which section markup to write | `npx wingo-ui@latest agents install claude` |
| Installed sections | Layout, spacing, mobile behavior, motion | `npx wingo-ui@latest add <slugs>` |
| Tokens and defaults | Colors, the main action's tone, backgrounds | `app/globals.css` and `UIProvider` |
| Rules file | Copy, proof, section order, what to check | `docs/LANDING.md` plus a project skill |

## Step 1: How do you connect Claude Code to real sections?

Run these in the project root. `login` stores a key for the CLI (a free account works for free items), and `agents install claude` writes the MCP entry to `.mcp.json`, a block in `CLAUDE.md` and a `wingo-ui` skill in `.claude/skills/`, which tell Claude Code to search the library before it writes UI. Without `WINGO_UI_API_KEY` in your environment, the MCP entry runs through a local stdio proxy that uses the key from `login`:

```bash
npx wingo-ui@latest init
npx wingo-ui@latest login
npx wingo-ui@latest agents install claude
```

If you prefer to add the server by hand, the [MCP docs](https://wingo-ui.com/docs/mcp) list the command:

```bash
claude mcp add --transport http wingo-ui https://wingo-ui.com/mcp --header "Authorization: Bearer $WINGO_UI_API_KEY"
```

Restart Claude Code and check `/mcp`. The tools that matter for a landing page are `search_components` (find sections by keywords), `get_component` and `get_block` (props with their defaults, the parts and the install command), `get_design_rules` and `get_theme_tokens`. With those, Claude reads `layout?: "centered" | "split" | "stacked" | ...` from the source of truth instead of guessing a prop name.

Then install the sections. Doing it yourself keeps the first agent session about copy and composition. The hero and pricing sections are Pro items, so this line needs a Pro key; the other four install with a free one:

```bash
npx wingo-ui@latest add hero-section pricing-section faq-section cta-section marketing-header marketing-footer
```

## Step 2: How do you set tokens so Claude stops picking colors?

Leave the components alone and change the tokens. The sections read semantic variables, so one block in `app/globals.css` turns the brand color from our orange into yours in both themes. The [theme generator](https://wingo-ui.com/theme) exports the same block if you want to pick it visually:

```css
/* app/globals.css, below the tokens that init wrote */
:root {
  --brand: #0f766e;
  --brand-foreground: #ffffff;
  --brand-soft: #e6f4f1;
  --brand-soft-foreground: #0b5c55;
}

.dark {
  --brand: #14b8a6;
  --brand-foreground: #04201d;
  --brand-soft: #0b2a27;
  --brand-soft-foreground: #5eead4;
}
```

Then put the page-wide choices into provider defaults, so the shortest JSX Claude writes is already on brand. Every section reads its defaults by its slug, and explicit props still win:

```tsx
// app/providers.tsx
"use client";

import type { ReactNode } from "react";
import { UIProvider } from "@/lib/ui-config";

const DEFAULTS = {
  "hero-section": { background: "grid", ctaTone: "brand", socialProof: false },
  "pricing-section": { tone: "brand" },
  "cta-section": { ctaTone: "brand", socialProof: false, showChecklist: false },
};

export function Providers({ children }: { children: ReactNode }) {
  return <UIProvider defaults={DEFAULTS}>{children}</UIProvider>;
}
```

`socialProof: false` matters most here. The hero and CTA sections ship with sample proof ("Loved by 12,000 teams", avatars, a rating) so their demos look finished. That copy belongs to the fictional Acme, not to you. Turning it off by default means Claude has to add proof deliberately, with real data.

## Step 3: What goes in a Claude Code landing page skill?

A rules file with the facts and the bans, and a small skill that loads it whenever the task is the landing page. Keep the facts in the file, because the model cannot invent what it can read:

```md
<!-- docs/LANDING.md -->
# Home page rules

Product: Northwind Invoices, invoicing for freelancers.
Offer: send an invoice in two minutes, automatic reminders, card payments.
Audience: freelancers and two-person studios in the US. Prices in USD.

## Sections, in order
1. Header (marketing-header)
2. Hero (hero-section, layout split, real screenshot in BrowserFrame)
3. Pricing (pricing-section, plans from lib/plans.ts)
4. FAQ (faq-section, 4 to 6 questions from docs/support-questions.md)
5. Closing CTA (cta-section)
6. Footer (marketing-footer)

## Never
- Numbers, customer counts, ratings, logos or quotes that are not in docs/proof.md
- Default sample copy from a component (Acme, 12,000 teams, a 14-day trial, Most popular, a support reply time)
- Gradient text, emoji as icons, hex colors or Tailwind palette classes (bg-purple-500)
- More than one brand-colored button per section

## Check before you say done
- grep the page for digits and compare each number with docs/proof.md
- screenshots at 390px and 1440px, light and dark
```

```md
<!-- .claude/skills/landing-page/SKILL.md -->
---
name: landing-page
description: Use for any change to the marketing home page (app/page.tsx or components/home/*). Reads docs/LANDING.md first.
---

Read docs/LANDING.md before writing anything. Search Wingo UI with search_components
before writing a section by hand, and read its props with get_component. Replace
every default label that states a fact. Run the checks at the end of LANDING.md.
```

The skill's description is what Claude Code sees at the start of a session, so it names the files that trigger it. Our post on [AGENTS.md vs CLAUDE.md](https://wingo-ui.com/blog/agents-md-vs-claude-md-react) covers where the always-on rules go, and the [Claude Code design system](https://wingo-ui.com/blog/claude-code-design-system) tutorial adds a hook that greps every edited file for hex colors.

## Step 4: Which Claude Code landing page prompts work?

Short ones that cover one section and name the component, the copy, what to leave out and the check. A Claude Code landing page prompt for the whole page at once gives the model too many open choices again. Here is the sequence for our page.

### Prompt 1: plan, install nothing

> Read docs/LANDING.md. For each section, tell me which Wingo UI component you will use, which props you will set, and which copy you still need from me. Write no code yet.

This surfaces gaps while they are cheap. If the plan lists a testimonials section, the rules file failed and you fix it there.

### Prompt 2: the hero

> Build the hero in app/page.tsx with HeroSection, layout split. Title and description from docs/LANDING.md. Primary action "Start free" to /signup, secondary "See pricing" to #pricing. Replace the default mockup with public/shots/invoice-editor.png inside BrowserFrame. No announcement pill.

Naming the screenshot matters. The default media is a drawn workspace for the sample product, and a drawing of someone else's app is another tell.

> Live demo (Hero Section): The split layout on the grid background with social proof off: copy and actions on the left, the product shot on the right. Make the window narrow and the shot moves under the actions. Try it at [Hero Section](https://wingo-ui.com/components/hero-section) and install it with `npx wingo-ui@latest add hero-section`.

### Prompt 3: pricing from real data

> Add PricingSection with id "pricing" and the plans from lib/plans.ts. Featured plan: pro, with the pill labeled "Recommended". Hide the compare link, we have no compare page. Set the footnote to "Prices in USD. Cancel any time." Read get_component first and do not invent prop names.

The footnote and pill lines are there because the defaults say "Paid plans start with a 14-day free trial" and "Most popular". If your product has no trial and no customers yet, both are false on your page.

> Live demo (Pricing Section): Flip the billing toggle to yearly: every price rolls to its yearly amount, and the Yearly option carries a savings pill worked out from the prices. Below 768px the plans become a swipeable rail that opens on the featured plan. Try it at [Pricing Section](https://wingo-ui.com/components/pricing-section) and install it with `npx wingo-ui@latest add pricing-section`.

### Prompt 4: FAQ and closing CTA

> Add FaqSection with the questions in docs/support-questions.md, layout centered, jsonLd on, no categories, no contact card. Then a CtaSection: title "Send your next invoice with Northwind Invoices", primary "Start free" to /signup, secondary "Read the docs" to /docs.

### Prompt 5: the check

> Run the checks at the end of docs/LANDING.md. List every number on the page with its source, and every place where a component still shows its default copy. Then screenshot / at 390px and 1440px in light and dark and tell me what overlaps or wraps badly.

Keep this step even when the page looks right. An agent that reviews its own output against a written list has something concrete to find, like sample copy it forgot; asked "does it look good?", it has nothing to check against.

## What does the finished page look like in code?

The page stays a Server Component, so metadata lives next to it, and every section is a client component imported directly. Props that the provider already sets are left out:

```tsx
// app/page.tsx
import type { Metadata } from "next";
import Image from "next/image";
import { BrowserFrame, HeroSection } from "@/components/blocks/hero-section";
import { PricingSection, type PricingSectionPlan } from "@/components/blocks/pricing-section";
import { FaqSection, type FaqItem } from "@/components/blocks/faq-section";
import { CtaSection } from "@/components/blocks/cta-section";

export const metadata: Metadata = {
  title: "Northwind Invoices: invoicing for freelancers",
  description: "Send an invoice in two minutes, get automatic reminders and take card payments.",
};

const PLANS: PricingSectionPlan[] = [
  {
    id: "free",
    name: "Free",
    description: "For your first clients.",
    price: 0,
    features: ["3 clients", "Unlimited invoices", "Card payments"],
    cta: { label: "Start free", href: "/signup" },
  },
  {
    id: "pro",
    name: "Pro",
    description: "For a full client list.",
    price: { monthly: 12, yearly: 10 },
    featuresTitle: "Everything in Free, plus:",
    features: ["Unlimited clients", "Automatic reminders", "Recurring invoices", "Your logo on invoices"],
    cta: { label: "Start with Pro", href: "/signup?plan=pro" },
  },
];

const FAQ: FaqItem[] = [
  { question: "Do you take a cut of my payments?", answer: "No. You pay the card processor's fee and nothing else." },
  { question: "Can I import clients from a spreadsheet?", answer: "Yes. Upload a CSV with a name and an email column." },
  { question: "What happens when I cancel Pro?", answer: "You keep every invoice and drop back to three active clients." },
];

export default function HomePage() {
  return (
    <main>
      <HeroSection
        announcement=""
        layout="split"
        title="Send an invoice in two minutes and get paid on time"
        description="Northwind Invoices drafts the invoice from your hours, sends reminders when it is late and takes card payments."
        labels={{ primary: "Start free", secondary: "See pricing" }}
        hrefs={{ primary: "/signup", secondary: "#pricing" }}
        media={
          <BrowserFrame url="invoices.example.com">
            <Image src="/shots/invoice-editor.png" alt="The invoice editor with two line items and a Send button" width={1600} height={1000} priority />
          </BrowserFrame>
        }
      />
      <PricingSection
        id="pricing"
        title="One price, no percentage of your invoices"
        description="Start free with three clients. Upgrade when you have more."
        plans={PLANS}
        featuredPlan="pro"
        showCompare={false}
        labels={{
          billedMonthly: "billed monthly",
          billedYearly: "billed yearly",
          popular: "Recommended",
          footnote: "Prices in USD. Cancel any time.",
        }}
      />
      <FaqSection
        description="Payments, imports and what happens when you cancel."
        items={FAQ}
        showCategories={false}
        contact={false}
        jsonLd
      />
      <CtaSection
        title="Send your next invoice with Northwind Invoices"
        description="Free for your first three clients. No card needed."
        labels={{ primary: "Start free", secondary: "Read the docs" }}
        hrefs={{ primary: "/signup", secondary: "/docs" }}
      />
    </main>
  );
}
```

Two defaults are replaced here that are easy to miss: the featured plan's "Most popular" pill (a claim a new product cannot make) and the FAQ's contact card, which promises a reply within one business day. Wrap `{children}` in `app/layout.tsx` with the `Providers` from step 2, and put the header and footer there too if other marketing pages share them. Give the header your own `items` and the footer your own `columns`, `legalLinks` and `socials`, since their defaults are Acme's sample navigation.

> Live demo (CTA Section): The closing band with the brand tone on the primary action. The avatars and the checklist under it are sample claims: on your page, set socialProof and showChecklist to false or fill them with real data. Try it at [CTA Section](https://wingo-ui.com/components/cta-section) and install it with `npx wingo-ui@latest add cta-section`.

## How do you check the page before it ships?

Look at it yourself, after the agent's check. Go through four things:

1. **Numbers.** Search the rendered page for digits. Each one needs a source you could show a customer.
2. **Default copy.** Search for the sample product name. In Wingo UI sections it is "Acme".
3. **Phone width.** At 390px the split hero stacks, the actions go full width and the pricing cards become a rail. Read the headline at that width; long words in a big font are where wrapping goes wrong.
4. **Both themes.** Your brand color has a light and a dark value for a reason. Check that the primary button and the soft tints read well in dark mode.

Our [Next.js SaaS landing page guide](https://wingo-ui.com/blog/nextjs-saas-landing-page) goes through what each section has to prove and what to cut when you have no proof yet.

## Should you start from the full template instead?

If your page follows the usual SaaS order, yes. The [Landing Page template](https://wingo-ui.com/templates/landing-page) composes the hero, logos, bento features, a product tour, numbers, quotes, a pricing teaser, the FAQ and the CTA, with a `design` prop (`classic`, `bold`, `editorial`, `minimal`) that picks every section's look at once, and `show*` props to drop sections you cannot fill honestly. For a Claude Code home page that is the shortest path: one prompt to swap the content, one to turn off sections, one for the check.

Separate sections are the better choice when you need a different order, a section the template does not have, or only three of them, as in this tutorial. The Landing Page template, Hero Section and Pricing Section are part of [Wingo UI Pro](https://wingo-ui.com/pricing); the FAQ Section, CTA Section, Marketing Header and Marketing Footer are free.

For the agent side in more depth, the [component library MCP guide](https://wingo-ui.com/blog/component-library-mcp-guide) covers what the server returns and how a full session runs, and [the shadcn MCP setup for Claude Code](https://wingo-ui.com/blog/claude-code-shadcn-mcp-setup) shows how to run two registries side by side.

## What is the next step?

Start with the free parts. A free account (email only, no card) gives the CLI and the [MCP server](https://wingo-ui.com/docs/mcp) a key for every free item. Run `npx wingo-ui@latest login` and `npx wingo-ui@latest agents install claude`, then install the closing band and the FAQ:

```bash
npx wingo-ui@latest add cta-section faq-section
```

Then write your `docs/LANDING.md` before the first prompt. Good Claude Code landing page design starts with the rules file: it is the part that keeps the page yours.

## Components in this post

- [Landing Page](https://wingo-ui.com/templates/landing-page) (Pro): A SaaS home page: hero with a drawn product shot, logos, bento features, product tour, numbers, quotes, pricing teaser, FAQ and CTA. Install: `npx wingo-ui@latest add landing-page`
- [Hero Section](https://wingo-ui.com/components/hero-section) (Pro): A React hero section for a landing or product page: an announcement pill, a big title, two actions, social proof and a product shot drawn in code. Install: `npx wingo-ui@latest add hero-section`
- [Pricing Section](https://wingo-ui.com/components/pricing-section) (Pro): A compact plans section for a landing page: plans with a Monthly / Yearly switch, a highlighted plan, checklists and a button each. Install: `npx wingo-ui@latest add pricing-section`
- [CTA Section](https://wingo-ui.com/components/cta-section) (Free): A React CTA section that closes a landing page: a title, two actions or an email signup, social proof and a short checklist on a band. Install: `npx wingo-ui@latest add cta-section`
- [FAQ Section](https://wingo-ui.com/components/faq-section) (Free): A React FAQ section for marketing pages: an accordion, a split layout, an open grid or expandable cards, with topics and live search. Install: `npx wingo-ui@latest add faq-section`

## FAQ

### Can Claude Code build a landing page?

Yes. Claude Code writes the files into your project, installs packages and can run your dev server, so it can build a complete landing page in Next.js or plain HTML. The result depends on what it starts from: with no components, tokens or rules it falls back to the most common patterns it has seen.

### Is there a Claude Code landing page skill?

Community skills exist, such as the landing-page skill in jezweb/claude-skills, which generates one self-contained HTML file with Tailwind from a CDN (as of November 2026). For a page inside an existing Next.js app, a short project skill of your own that points at your rules file and components fits better.

### What is a good Claude Code landing page prompt?

One that covers a single section and names four things: the component to use, the real copy or where it comes from, what to leave out, and how to check the result. "Build a landing page for my app" leaves every one of those to the model.

### Why does my AI-generated landing page look generic?

Because every choice you did not make is filled with the most common answer: a centered gradient hero, three icon cards, a made-up customer count and invented testimonials. Fix the choices before the first prompt with tokens, a section list and a rules file.

### Should the landing page use a template or separate sections?

Use a full template when your page follows the usual SaaS order and you want a finished look fast. Use separate sections when you need a different order or only a few of them, since each one is configured through its own props.

---

Source: https://wingo-ui.com/blog/claude-code-landing-page
