~/codigoagente
AI agents

How to build a landing page with Claude Code by combining 4 skills (real test, errors included)

One skill does one thing well. The real value comes from combining them: in this guide we chain four public skills in Claude Code to build a landing page that sells, with a distinctive design, structured data and an SEO audit before it goes live. We actually did it, with a sample business, and here are the result, what it cost and the five errors we hit along the way, with their fixes.

If you have never installed a skill, start with the Claude Code skills guide.

Hero of the landing page generated without skills (cream background, serif and one word in orange italics) next to the one made with the 4 skills (condensed ink-blue headline and a large bicycle wheel)
Same business, same model. Left: Claude Code without skills; right: with all four · codigoagente

The recipe: 4 skills, one outcome

StepSkillRepository and licenseWhat it adds
1`copywriting` v2.3.2[coreyhaines31/marketingskills](https://github.com/coreyhaines31/marketingskills), MITSales copy with a method: it diagnoses the starting point, never invents numbers or reviews, and flags gaps with `[NEED]`
2`frontend-design`[anthropics/skills](https://github.com/anthropics/skills), Apache-2.0A visual direction of its own and a list of AI-generated design tells to avoid
3`schema` v2.0.2coreyhaines31/marketingskills, MITJSON-LD structured data that matches the visible content
4`seo-audit` v2.2.2coreyhaines31/marketingskills, MITTechnical, on-page and local SEO audit, ranked by priority

Order matters: the copy feeds the design, the design ships a first JSON-LD that schema fixes, and seo-audit reviews the whole page before launch. Each step leaves a file the next one reads (copy.md → index.html → auditoria-seo.md).

Test setup: Claude Code 2.1.316 on Linux, default model (Sonnet 5.5), skills CLI 1.7.4, marketingskills 2.14.0 (commit 88c79f6) and anthropics/skills at commit ca45fc4, on October 31, 2026.

The case: a landing page for a bike repair shop

To keep it realistic we used a made-up local business: Rueda Libre, a bike repair shop in Quito, Ecuador, with cargo-bike pickup and delivery, free diagnosis and quotes over WhatsApp. The page's single goal: get visitors to message on WhatsApp. The page itself is in Spanish, since that is the shop's market.

The marketingskills skills first look for a product context file (.claude/product-marketing.md) and, if it exists, skip the questions it already answers. That is the biggest time saver when you combine them: write it once and all three read it.

.claude/product-marketing.mdtext
# Product context: Rueda Libre (fictional test business)

- What: bike repair and maintenance shop in Quito (La Floresta).
- Services and prices (USD): basic tune-up 15; full overhaul 35; brakes and gears 8;
  inner tube change 5 + part; new bike assembly 25.
- Edge: cargo-bike pickup and delivery (north Quito, 3 USD); free diagnosis;
  WhatsApp quote before touching anything; most jobs back in 24 h.
- Audience: bike commuters, families, weekend road cyclists.
- Page goal: get them to message on WhatsApp.
- Voice: friendly, Ecuadorian Spanish. No invented reviews, stars or years in business.

Step 0: install the four skills

The skills CLI installs them into the project (.claude/skills/) with two commands:

terminalsh
npx skills add coreyhaines31/marketingskills --skill copywriting --skill schema --skill seo-audit --agent claude-code -y
npx skills add anthropics/skills --skill frontend-design --agent claude-code -y
Terminal output installing copywriting, schema and seo-audit from marketingskills and frontend-design from anthropics/skills into .claude/skills
The four skills copied into .claude/skills and recorded in skills-lock.json · codigoagente

The CLI also writes a skills-lock.json with a hash of every SKILL.md, handy to know if someone changed them. As the installer itself warns, skills run with the agent's full permissions: read them first (they are Markdown, five minutes each). To find other skills worth combining, find-skills does the search for you.

Step 1: the copy with copywriting

terminalsh
claude -p "/copywriting Escribe el copy de la landing page de Rueda Libre y guárdalo en copy.md." \
  --allowedTools "Read,Write,Edit,Glob,Grep,Skill"

The skill forces a three-way diagnosis first (A: start from scratch, B: a real voice to preserve, C: a point edit). Our copy.md opens with: *"Diagnosis: A. There is product context (services, prices, differentiators) but no previous draft or written brand voice."*

What impressed us most is what it did not do: it left the reviews section empty with a [NEED: real customer reviews or testimonials], did the same with the rejected-quote policy the brief didn't cover, and warned that the service descriptions were its own assumptions to confirm. Final headline: "Te recogemos la bici en casa y te la devolvemos lista" ("We pick up your bike at home and bring it back ready").

Step 2: the design with frontend-design

terminalsh
claude -p "/frontend-design Construye index.html, la landing de Rueda Libre, con el texto de copy.md tal cual (no reescribas el copy). Un solo archivo HTML con el CSS dentro, responsive, lista para publicar." \
  --allowedTools "Read,Write,Edit,Glob,Grep,Skill"

Anthropic's skill lists the five looks AI-generated design falls into: cream background with a serif and terracotta accent, near-black with one acid-green accent, broadsheet layout, the SaaS card kit, and template chrome (all-caps eyebrow labels over every heading, meta strings joined by middle dots, one headline word in a different color...).

The no-skills version (below) hits almost all of them. With the skill, Claude picked a "workshop" palette (concrete grey, ink blue and safety-vest orange), a condensed display face and one large wheel that spins on scroll as the page's only motion. Steps are numbered because they really are a sequence; nothing else is.

Three-step section on an ink-blue background and the pricing table of the final Rueda Libre landing page
Numbered steps (they are a sequence) and the pricing table, which stacks into cards on mobile · codigoagente

The first version still shipped with bugs. See errors 2 and 3.

Step 3: structured data with schema

terminalsh
claude -p "/schema Revisa los datos estructurados de index.html y déjalos completos y correctos para este negocio local. Edita index.html." \
  --allowedTools "Read,Write,Edit,Glob,Grep,Skill"

The design already shipped a basic JSON-LD. The skill fixed and extended it without inventing anything:

  • addressRegion said "La Floresta" (a neighborhood); it changed it to "Pichincha" (the province).
  • It added priceRange, currenciesAccepted, areaServed and a hasOfferCatalog with all six services and prices.
  • It did not add FAQPage, since Google no longer shows FAQ rich results for most sites, nor url, geo or image, because they didn't exist on the page.

Good judgment. It still missed the most serious error of the test (number 4).

Step 4: the audit with seo-audit

terminalsh
claude -p "/seo-audit Audita index.html antes de publicarla (SEO técnico y on-page, incluido SEO local). Guarda el informe en auditoria-seo.md, ordenado por prioridad. No edites index.html todavía." \
  --allowedTools "Read,Write,Edit,Glob,Grep,Skill"

The report has four priority levels, an action plan table and line-numbered evidence. The most useful findings:

  • 68-character title and 195-character meta description: Google truncates around 60 and 155. It proposed 56 and ~150 character versions.
  • The H1 lacked the main query ("taller de bicicletas Quito", bike repair shop Quito), which only appeared in the eyebrow. Instead of rewriting the headline itself, it asked for sign-off because that is a copy decision.
  • Missing canonical, robots.txt, sitemap.xml, og:image and a tel: link.
  • For local SEO, the Google Business Profile listing matters more than the site itself, and "north Quito" is too vague as a service area.
  • Two pieces of dead code (an unused CSS class and a getElementById for an id that doesn't exist).

We then asked Claude to apply the fixes that didn't need real business data (title, description, H1, tel:, navigation and cleanup). Canonical, og:image and geo were left pending on purpose: without a domain or real photos, any value would be made up.

The result: with and without skills

As a baseline, we ran the same request in a folder with no skills: *"Read contexto.md and create index.html: the landing page for that business, a single file with the CSS inside, ready to publish."*

No skillsWith the 4 skills
Claude Code runs16 (5 plus one that didn't load the skill)
Agent time1 min 38 s7 min 14 s
Cost (list price)0.29 USD1.58 USD
DesignCream, serif, orange accent, one italic word, monospace all-caps labels, 01/02/03 markersOwn palette and type, numbers only on the sequence
CopyFine, no visible methodDiagnosis, stated assumptions, gaps flagged with `[NEED]`
Title / description69 / 204 characters56 / 146 characters
H1 contains the main queryNoYes
JSON-LD`BicycleStore` (non-existent type), 5 properties`BikeStore`, 49 valid properties with a price catalog
Audit before launchNoYes, 12 prioritized actions

The no-skills version isn't bad: it's a decent landing page that could come from any template. The difference is that the combination works with a method (diagnosis, critique, audit) and writes down what's missing before you can really publish. For 1.29 USD more, that's a good deal. What it doesn't do on its own is check its own work, and that's where almost every error came from.

Mobile view: the first version with the sticky button covering text, and the fixed version with navigation and the full text
On mobile, the first version duplicated the button and covered "Diagnóstico gratis"; the fixed one hides it while the hero button is visible · codigoagente

The 5 errors we hit (and how we fixed them)

Error 1: the skill didn't load by itself

In the first run we asked *"Write the copy for the Rueda Libre landing page and save it to copy.md"*. The copywriting skill was in the list of available skills and its description literally includes "landing pages"... and Claude didn't use it. It wrote the copy its default way: Bash, Grep, Read and Write, no call to the Skill tool.

Terminal: the first run without a slash command doesn't use the copywriting skill; the second one with /copywriting starts with the skill's diagnosis A
Without /copywriting the skill never fired; with it, the copy opens with the diagnosis the skill requires · codigoagente

Fix: invoke it by name at the start of the prompt (/copywriting ...). We did that for all four steps. When you chain skills, don't rely on automatic activation: it decides which method gets applied.

Error 2: the design was built blind

frontend-design asks to "plan, review against the brief, build and critique", but in -p mode without permission to run commands, Claude can't open a browser. It said so: *"I couldn't see it rendered: the environment didn't let me run a browser"*. The first version had three bugs visible in a screenshot:

  • The H1 took five lines and the WhatsApp button fell below the fold on a 1440×900 laptop.
  • The wheel covered the end of the subtitle.
  • On mobile, the sticky bottom button duplicated the hero one and covered "Diagnóstico gratis".
First version of the hero: five-line headline, no visible button and the wheel covering the subtitle
The first version at 1440×900: the main button is off-screen and the wheel overlaps the text · codigoagente

Fix: we took 1440×900 and 390×844 screenshots with Playwright, saved them in capturas/ and handed them over:

terminalsh
claude -p "/frontend-design Abrí index.html en el navegador. Mira capturas/escritorio.png (1440x900) y capturas/movil.png (390x844), critica lo que ves contra el brief y corrige index.html. No cambies el copy." \
  --allowedTools "Read,Write,Edit,Glob,Grep,Skill"

Claude reads images, so it spotted all three bugs on its own, shrank the H1, moved the wheel and hid the sticky button while the hero one is visible. If you work interactively on your own machine, let it run a browser so it can close this loop by itself.

Error 3: the agent asked for permissions it didn't have

In that same fix, Claude tried to retake the screenshots with a Playwright script and the run stopped: *"This command requires approval"*. Since we only allowed Read, Write, Edit, Glob, Grep, Skill, it ended by saying the changes weren't visually verified.

Fix: we verified with fresh screenshots ourselves (the ones in this article). That's the right call in non-interactive mode: don't hand unrestricted Bash to an unsupervised agent just so it can take screenshots.

Error 4: the business type doesn't exist in schema.org

This is the big one. Both the no-skills and the with-skills versions marked the business as "@type": "BicycleStore". The schema skill accepted it and seo-audit called the JSON-LD "consistent with the visible text". That type doesn't exist: the right one is BikeStore.

We tried the Rich Results Test and the schema.org validator, but both were blocked from our test environment (CONNECT tunnel failed, response 403). So we downloaded the official schema.org vocabulary from its GitHub repository and checked it with a 43-line script:

checkld.pypython
import json, re, sys

grafo = json.load(open(sys.argv[1]))["@graph"]
def ids(x):
    if x is None: return []
    return [i["@id"] for i in (x if isinstance(x, list) else [x])]

padres, dominios, tipos = {}, {}, set()
for n in grafo:
    t = n["@type"] if isinstance(n["@type"], list) else [n["@type"]]
    if "rdfs:Class" in t:
        tipos.add(n["@id"]); padres[n["@id"]] = ids(n.get("rdfs:subClassOf"))
    if "rdf:Property" in t:
        dominios[n["@id"]] = ids(n.get("schema:domainIncludes"))

def ancestros(c, vistos=None):
    vistos = vistos or set()
    for p in padres.get(c, []):
        if p not in vistos: vistos.add(p); ancestros(p, vistos)
    return vistos | {c}

errores, ok = [], 0
def recorrer(o, ruta):
    global ok
    if isinstance(o, list):
        for i, x in enumerate(o): recorrer(x, f"{ruta}[{i}]")
        return
    if not isinstance(o, dict) or "@type" not in o: return
    clase = "schema:" + o["@type"]
    if clase not in tipos:
        errores.append(f"{ruta}: tipo desconocido {o['@type']}"); return
    for k, v in o.items():
        if k.startswith("@"): continue
        p = "schema:" + k
        if p not in dominios: errores.append(f"{ruta}.{k}: propiedad inexistente")
        elif not set(dominios[p]) & ancestros(clase): errores.append(f"{ruta}.{k}: no aplica a {o['@type']}")
        else: ok += 1
        recorrer(v, f"{ruta}.{k}")

html = open(sys.argv[2]).read()
for bloque in re.findall(r'<script type="application/ld\+json">(.*?)</script>', html, re.S):
    recorrer(json.loads(bloque), "$")
print(f"{ok} propiedades válidas, {len(errores)} errores"); print("\n".join(errores))

Run it with python3 checkld.py schemaorg-current-https.jsonld index.html. It prints the number of valid properties and every unknown type or property that doesn't apply to its type.

Terminal: the schema.org validator blocked, the local script flags the unknown type BicycleStore, and after switching to BikeStore it reports 49 valid properties and 0 errors
Local validation against the schema.org vocabulary: from a non-existent type to 49 valid properties · codigoagente

Fix: we told Claude in the fix-up step and it changed BicycleStore to BikeStore. Lesson: skills improve judgment, but they don't replace a validator. A JSON-LD block with a made-up type looks perfect at a glance, and Google just ignores it.

Error 5: title and description too long

The copy proposed a 68-character title and a 195-character description. Here the chain worked as intended: seo-audit caught it, suggested shorter versions and the fix-up step applied them (56 and 146 characters). One nice touch: Claude didn't paste the audit's description verbatim, which promised "delivery in 24 hours", but kept "most in 24 hours" so it wouldn't promise more than the page does.

How to repeat it in your project

  1. Write .claude/product-marketing.md with product, prices, audience, goal and voice. Every marketingskills skill reads it.
  2. Install the four skills with the two npx skills add commands.
  3. Run each step invoking the skill by name (/copywriting, /frontend-design, /schema, /seo-audit) and have each step leave a file for the next.
  4. After the design step, take desktop and mobile screenshots and ask for a critique based on them.
  5. Validate the JSON-LD with the Rich Results Test (or the script above) before publishing.
  6. Apply the audit and write down what needs real data: domain, photos, coordinates, reviews.

If you want a full development workflow instead of a landing page (planning, TDD, review), the combination that has worked best for us is Superpowers.

FAQ

Do I have to pay for the skills? No. All four are public: marketingskills is MIT licensed and frontend-design is Apache-2.0. You pay for Claude Code usage: 1.58 USD at list price with Sonnet 5.5 in our test.

Why not use a single skill that does everything? Because each one brings its own proven method (copy, design, structured data, audit). Combined, they review each other's work: schema fixed the design's JSON-LD and seo-audit fixed the copy's title.

Does it work with Codex, Cursor or other agents? Skills are SKILL.md files, and the skills CLI installs them for several agents with --agent. We only tested Claude Code.

Do the skills make up reviews or data? Not in our test: copywriting left social proof empty with [NEED] and schema added no geo or image without data. The BicycleStore type was a made-up error, though, and neither skill caught it.

Can I run it without -p mode? Yes, and it's better for the design step: in an interactive session you can let it open a browser and critique its own screenshots without you stepping in.

Conclusion

Four well-chained skills turn "make me a landing page" into a process with a method: copy with verifiable claims, a design with its own identity, structured data and an audit before launch, in seven minutes of agent time and under two dollars. What they don't give you is verification: invoke each skill by name, show the design step screenshots and validate the JSON-LD before you ship. If this is your first time with skills, continue with the Claude Code skills guide.

// source code

Repositories in this article
The code this article covers is public: browse it, star it or clone it from here.

// implementation

Need this automation running in your business?
Don't spend weeks wiring servers, APIs and agents. Safe Build Labs, the agency that sponsors codigoagente, builds it for you, production-ready.
We tested mcp-builder, Anthropic's official skill for building MCP servers: one for a small shop in 99 seconds for 0.25 USD, plus two version bugs to avoid.
  • Skills for your agents
  • Claude Code
read article
We tested webapp-testing, Anthropic's official skill that tests your local web app with Playwright: setup, with_server.py, two real pitfalls and what it costs.
  • Skills for your agents
  • Claude Code
read article
video-shotcraft is an Apache-2.0 skill with 150 shots that lets Claude Code build your product's promo video in Remotion. How it works and what it costs.
  • Skills for your agents
  • Claude Code
read article