Free: 96 PPC tools + my AI Playbook book
Tools
Free
How to build a world-class marketing website with Claude Code
Stewart Dunlop, founder of PPC.io
Stew built this / founder, PPC.io

I rebuilt the Flock events site in 5 days from an empty repo using Claude Code (see /built-with-claude). This is the exact playbook — adapted so you can do the same for your own marketing site without writing a single line of code yourself.

1 Step 1: Install Claude Code + Vercel
2 Step 2: Mockup every screen in ChatGPT image gen
3 Step 3: Paste the kickoff prompt
4 Step 4: Iterate section by section (with the anti-slop guardrails)
5 Step 5: Lock down security before you go live
6 Step 6: If you're rewriting an existing site, map every URL

How to build a world-class marketing website with Claude Code

You came here from the YouTube video. No coding required from you. ChatGPT mocks the screens, Claude Code writes the code, Vercel hosts it. The same playbook I used to ship the Flock events site in 5 days from an empty repo.

⚠️ The single most important rule. If you get stuck, see an error you don’t understand, or your site looks like generic AI slop — paste the problem back into Claude Code and ask it for the path forward. That’s the whole game. You can’t break it. The site lives in version control; you can roll back anything at any time.


What you’ll have at the end

A real production marketing site. Custom domain. SSL. CDN. Preview URL on every branch. Tight CSP. Security headers. Bot-protected forms. A sitemap. URL redirects if you’re migrating from an old site. And — most importantly — a CLAUDE.md + BRAND.md in the repo that prevents every new page you build from drifting back into generic AI slop.

If you haven’t done the Claude Code setup guide yet, do it first — takes 30 minutes and unlocks the rest of this. Then come back.


Step 1 — Sign up for Vercel

Vercel hosts marketing sites for free. Push code, it deploys. SSL, global CDN, preview URLs per branch — all included. No credit card.

👉 Sign up at vercel.com → Click “Continue with GitHub” so Claude Code can push your code to a repo it controls.

🔒 Security note up-front. Never paste a Vercel access token (the vcp_… strings) into Claude Code or any other chat. Account-scoped tokens — leaking one means full account compromise. When Claude Code needs to talk to Vercel, it’ll prompt you to run vercel login in your terminal, which opens an OAuth flow in your browser. Use that. Always.


Step 2 — Mockup every screen in ChatGPT (image gen)

This is the secret. Don’t ask Claude Code to “design a beautiful homepage.” Show it a picture.

Open ChatGPT, prompt the image generator with one screen at a time. Be brutally specific:

A modern marketing-site hero section in dark mode. Centered headline
in a serif display font, single line. Soft purple-pink gradient
behind the word "yours" only. Below: a 14-word subhead in light-grey
sans-serif. Single primary button, rounded pill, lavender fill.
Below the fold: a 5-photo bento grid, 16:9 aspect, irregular sizes.
No emoji. No icon clutter. Reference: Linear's landing page hero.

Save the screenshot. Repeat for every page (homepage, pricing, about, contact, blog index). 30 minutes of iteration in ChatGPT saves you 5 hours of “make it look better please” with Claude Code.

💡 The tip that matters. Describe the feeling with named references. “Linear-style ruthless typography.” “Stripe-grade restraint.” “Vercel docs but warmer.” Claude Code (and ChatGPT’s image gen) both respond ten times better to “make it feel like X” than to abstract adjectives like “modern” or “clean.”


Step 3 — Paste the kickoff prompt into Claude Code

This single prompt sets up the whole project foundation: Astro + Tailwind scaffold, security baseline middleware, brand system files, Vercel project + first preview deploy. About 20 minutes of clicks and confirmations.

Open Claude Code. Paste this entire block. Hit enter.

You're going to set me up to build a production marketing website
using Claude Code. I am NOT a developer. Walk me through everything
one step at a time, ask me to confirm before each step, and if I
get confused just rewrite the instruction in simpler words.

Do these in order:

1. Ask me four questions:
   - What's the domain (e.g. example.com)?
   - What does the business do, in one sentence?
   - Who is the customer (one sentence)?
   - What design feeling am I going for (give me 2-3 reference sites
     I admire and what I like about each)?

2. Create a new project folder at ~/<repo-name> (pick a short slug
   based on the business name). Initialise git. Set up an Astro
   project with Tailwind CSS, the @astrojs/sitemap integration, and
   the @astrojs/vercel adapter. Astro because it's static-first,
   ships zero JS by default, and Vercel deploys it in seconds.

3. Create a CLAUDE.md at the project root with:
   - The four answers from step 1
   - Instructions to future Claude sessions to ALWAYS read BRAND.md
     before making any visual decision
   - A non-negotiables list: never invent colors or fonts; never use
     border-left accent strips; never apply purple-glow shadows to
     non-CTA elements; never use linear-gradient backgrounds on
     cards; never apply backdrop-filter: blur() as a default; never
     do hover-lift with translateY alone; never put emojis in body
     copy; never use uppercase headlines; never use generic system
     fonts like Inter when the brand has a specific display face.

4. Create a BRAND.md at the project root that captures:
   - Color tokens (ask me — primary, accent, surface, ink, muted)
   - Font choices (display + body + mono, with Google Fonts or
     Adobe Typekit URLs)
   - Spacing scale, radius scale, shadow scale (use the same scales
     Tailwind defaults to unless I have a system)
   - A "voice and tone" paragraph the homepage copy should follow

5. Set up the project skeleton:
   - src/pages/index.astro (homepage placeholder)
   - src/layouts/MainLayout.astro
   - src/components/Nav.astro and Footer.astro
   - src/styles/globals.css with the brand tokens from BRAND.md
   - public/robots.txt and a sitemap config in astro.config.mjs
   - Open Graph image placeholder at public/og.png (I'll replace later)

6. Set up the security baseline NOW, before any content:
   - A middleware.ts that sets Content-Security-Policy, HSTS,
     X-Frame-Options, X-Content-Type-Options, Referrer-Policy, and
     Permissions-Policy headers on every response
   - A .gitignore that excludes .env, .env.local, and any *.key file
   - A .env.example with placeholders only, no real values
   - Document in CLAUDE.md that ALL secrets live in Vercel env vars,
     never in code

7. Install Vercel CLI globally. Run `vercel login` (this opens a
   browser OAuth flow — do NOT prompt me for an access token). Then
   `vercel link` to create the Vercel project.

8. Push the empty skeleton to a new GitHub repo (ask me for the
   repo name and visibility). Connect the GitHub repo to Vercel so
   every push to main auto-deploys.

9. Run a first deploy to a preview URL. Open the preview URL in my
   browser so I can see "hello world" working before we touch any
   real content.

When all 9 are done, tell me to paste my first mockup screenshot
and you'll build the homepage hero from it. If anything errors —
diagnose it and walk me through the fix. I'll paste error messages
back.

When Claude finishes, you’ll be looking at a live Vercel preview URL of your skeleton site. The plumbing is done. Time to make it look like something.


Step 4 — Iterate section by section, with anti-slop guardrails

Once the skeleton is live, you build the real site one mockup at a time:

Build the homepage hero from this mockup [paste screenshot].
Match the layout, type sizes, and spacing exactly. Use the tokens
in BRAND.md. Read CLAUDE.md for the non-negotiables. After you
build it, deploy to preview and tell me the URL.

First pass will look sloppy. Generic fonts will sneak in. Default colors will appear. Cards will get gradient backgrounds. Hover states will be lazy translateY lifts. This is normal — Claude’s defaults are “average SaaS,” not “world-class.”

Your job is to direct it past those defaults with specific feedback. Here’s the cheat sheet:

The AI-slop defaultPush back with
Generic Inter on Inter on Inter”Swap body font to Figtree. Display font to Outfit Bold Italic on the hero only.”
Purple-everywhere AI palette”Drop the purple. Primary accent is #FF6B35. Surface is #F8F4EE. Ink is #0A0A0A.”
border-left: 4px solid accent strips”Remove the accent strip. The accent lives in the content — a colored chip, an italic word, not in the chrome.”
Gradient backgrounds on cards”Cards are solid. Gradients are reserved for the CTA button and one decorative sheen line per section.”
backdrop-filter: blur() everywhere”Blur is for the sticky nav only. Everything else is opaque.”
Lazy translateY(-6px) hover”Hover combines a 2px lift with a -1deg rotation, and the shadow softens — not strengthens.”
Emojis in body copy”No emojis in prose. Use Phosphor icons inline.”
UPPERCASE H1/H2”Uppercase is for eyebrow labels only. Headlines are sentence case.”

The pattern: don’t say “make it nicer.” Say “swap X to Y because Z.” Reference real sites by name. Paste screenshots of details you want to copy. Specificity is the entire skill.

📝 Update BRAND.md as you go. Every time you push back on a default, write that rule into BRAND.md so future Claude sessions don’t repeat the same mistake on the next page. After a week of building, your BRAND.md becomes a brand system that prevents 90% of the slop automatically — Claude reads it before every render.


Step 5 — Lock down security before you go live

Security isn’t a “we’ll do it later.” Wire it in before the site has real traffic — retrofitting CSP and dependency hygiene is painful once a hundred third-party scripts are already on the page.

⚠️ The stakes. Your contact form will get hit by bots within 24 hours of going live. Hardcoded API keys in client bundles get scraped by GitHub crawlers in minutes. A loose CSP turns one XSS bug into a credential-stealing pipeline. None of this is paranoia — it’s the default state of the internet.

Paste this into Claude Code right after Step 4 feels stable:

Run a security pass on this site. Specifically:

1. Audit CSP. List every domain in my script-src, style-src,
   font-src, img-src, connect-src, frame-src directives. Anything
   I don't recognise — flag it. The goal is the tightest possible
   policy that still works.

2. Scan the entire repo for hardcoded secrets, API keys, tokens,
   or credentials. Flag any client-side bundle that contains an
   environment variable starting with anything other than PUBLIC_.

3. Check every form on the site. Every one must have: rate limiting
   on the backend handler, a honeypot field, and (if it's contact
   or signup) Cloudflare Turnstile or hCaptcha. List any form that
   doesn't.

4. Check security headers. I should have HSTS with includeSubdomains
   and preload, X-Frame-Options DENY (unless I'm intentionally
   embeddable), X-Content-Type-Options nosniff, Referrer-Policy
   strict-origin-when-cross-origin, and a sensible Permissions-Policy.

5. Run `npm audit` and tell me about any high or critical advisories.
   For each, recommend the safest path: patch, replace, or accept
   with justification.

6. Set up Dependabot or Renovate to alert me to new vulnerabilities
   in dependencies going forward.

Tell me what you found and what to fix in priority order.

Common things you’ll need to handle as you launch:

  • Form spam. Cloudflare Turnstile is free and invisible to real humans. Add it to every form, not just the obvious ones.
  • Vercel preview URLs are guessable. Turn on Deployment Protection (“Only Preview Deployments” mode) in Vercel project settings if your previews show sensitive content.
  • Analytics scripts inflate your CSP. Be deliberate about what you include. Cookiebot, GTM, Clarity all need their domains whitelisted — each one widens your attack surface.
  • Don’t embed iframes from random hosts. Each one expands frame-src and gives an attacker a foothold.

Step 6 — If you’re rewriting an existing site, map every URL

This is where most rewrites destroy 6-12 months of SEO. Don’t change URLs unnecessarily. Every URL change is a redirect; every redirect costs link equity.

Paste this:

I'm rewriting an existing site at <domain>. Here's the current
sitemap: <paste sitemap.xml content OR give me the URL>.

For every existing URL:
1. Decide: does the new site have an equivalent page?
2. If yes and the URL is the same: no action.
3. If yes and the URL changes: add a 301 redirect from old to new
   in middleware.ts (or vercel.json if static).
4. If no equivalent: redirect to the closest match (not the
   homepage — Google penalises mass-redirect-to-root).

Output: a complete redirect table I can paste into middleware.ts.
Then write a verification script that hits every old URL and
confirms it 301s to the right destination.

After I deploy, walk me through:
- Submitting the new sitemap to Google Search Console
- Using GSC URL inspection to verify Googlebot sees the redirects
- Running a Lighthouse audit on the top 5 pages and fixing anything
  scoring below 90 on Performance, Accessibility, or SEO.

The free performance dividend. Vercel’s CDN gets you 90+ Lighthouse Performance for free if you don’t sabotage it. Don’t import all 1,200 weights of every Google Font. Don’t ship JavaScript you don’t need. Don’t load video on page load. Astro defaults are good — keep them.


Step 7 — Custom domain + go live

In Vercel project settings → Domains, add your custom domain. Vercel tells you which CNAME or A records to add at your registrar. Add them. SSL provisioning is automatic (~5 minutes).

When your site loads on the custom domain in an incognito tab — you’re live.


Quick reference

ThingWhere it lives
Project repo~/<your-repo>/ (Claude Code created this)
Brain Claude auto-readsCLAUDE.md (your non-negotiables)
Design tokens + voiceBRAND.md (update as you iterate)
SecretsVercel env vars dashboard — never in code
Mockup pipelineChatGPT image gen → screenshot → paste into Claude Code
DeploysAuto on every push to main
When stuckAsk Claude Code. Always.

Built by Stewart Dunlop · PPC.io. Want to see this playbook applied to a real client site? See the Flock case study →. Reply on any YouTube video if anything is unclear and I’ll fix this guide.

Want this on autopilot?

This is the manual version of How to build a world-class marketing website with Claude Code.

Install once, configure, run when you remember.
PPC.io runs the same analysis on a schedule and alerts you when something changes.
Join the waitlist
Connect your Google Ads account and run your first audit in under 15 minutes.
Join the waitlist, and get FREE beta access to the tool
Enter your email address
Closed beta. We're letting people in slowly.
Free during beta. No credit card required. Stewart reads every reply.
Thank you for joining our waitlist