
Landing Page Generator
- 101 installs
- 451 repo stars
- Updated July 21, 2026
- borghei/claude-skills
landing-page-generator is a skill that builds high-converting landing pages using copy frameworks (PAS, AIDA, BAB), an ordered section library, CTA strategy, and conversion optimization.
About
This skill generates high-converting landing pages using proven copy frameworks (PAS, AIDA, BAB), an ordered section library, and conversion optimization techniques. It covers hero design, social proof, CTA strategy, SEO meta, Core Web Vitals, and A/B testing. Marketers use it to build campaign, lead-capture, and conversion pages that match the traffic source's message.
- Builds landing pages using PAS, AIDA, and BAB copy frameworks matched to audience awareness
- Provides a 10-section page order plus a conversion optimization checklist
- Covers CTA strategy, SEO meta, Core Web Vitals, and A/B testing of headline and CTA variants
Landing Page Generator by the numbers
- 101 all-time installs (skills.sh)
- Ranked #1,144 of 1,879 Marketing & SEO skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
landing-page-generator capabilities & compatibility
- Capabilities
- copywriting · conversion optimization · ab testing · seo
- Use cases
- copywriting · marketing · seo · web design
- Pricing
- Free
What landing-page-generator says it does
Design and build high-converting landing pages using proven copy frameworks, section patterns, and conversion optimization techniques.
Choose copy framework (PAS, AIDA, BAB) based on audience awareness
The landing page headline MUST match the ad/email that drives traffic:
npx skills add https://github.com/borghei/claude-skills --skill landing-page-generatorAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 101 |
|---|---|
| repo stars | ★ 451 |
| Last updated | July 21, 2026 |
| Repository | borghei/claude-skills ↗ |
What it does
Generate a high-converting landing page with copy framework, section order, CTA strategy, and conversion checklist.
Who is it for?
Marketers building campaign, lead-capture, or conversion landing pages that match a specific traffic source.
Skip if: Multi-page site navigation or content marketing articles that are not single-goal conversion pages.
When should I use this skill?
You need to create a landing page, campaign page, lead capture page, or conversion page.
What you get
Produces an ordered, framework-driven landing page with matched copy, CTA strategy, and a conversion checklist.
- Landing page structure and copy
- CTA strategy
- Conversion optimization checklist
By the numbers
- 10-section page order from hero to final CTA
- Three copy frameworks: PAS, AIDA, BAB
- Four design styles: dark-saas, clean-minimal, bold-startup, enterprise
Files
Landing Page Generator
Design and build high-converting landing pages using proven copy frameworks, section patterns, and conversion optimization techniques.
---
Table of Contents
- Keywords
- Quick Start
- Core Workflows
- Page Section Library
- Copy Framework Application
- Conversion Optimization Checklist
- Design Style Reference
- CTA Strategy
- SEO and Performance
- A/B Testing Framework
- Best Practices
- Integration Points
---
Keywords
landing page, landing page design, conversion optimization, lead capture page, campaign page, marketing page, hero section, CTA strategy, landing page copy, landing page generator, promo page, conversion page, lead gen page, single-page site, landing page template, A/B testing, page layout, above the fold, social proof, pricing table, FAQ section, testimonial block
---
Quick Start
Generate a Landing Page
1. Gather inputs: product, audience, pain point, key benefit, offer 2. Select design style (dark-saas, clean-minimal, bold-startup, enterprise) 3. Choose copy framework (PAS, AIDA, BAB) based on audience awareness 4. Build sections in order: Hero > Problem > Solution > Social Proof > How It Works > CTA 5. Run conversion optimization checklist before publishing 6. Set up A/B test for headline and CTA variants
Landing Page Brief Template
## Landing Page Brief
- Product/Service: [Name]
- Value proposition: [One sentence]
- Target audience: [Who and what they need]
- Key pain point: [Primary problem you solve]
- Key benefit: [Primary outcome they get]
- Offer: [What you are offering — trial, demo, download, purchase]
- Traffic source: [Where visitors come from — ads, email, organic]
- Design style: [dark-saas / clean-minimal / bold-startup / enterprise]
- Copy framework: [PAS / AIDA / BAB]---
Core Workflows
Workflow 1: Full Landing Page Build
Step 1: Define the Single Goal
Every landing page has one purpose and one CTA. Define it before anything else:
- What action do you want the visitor to take?
- What does the visitor get in return?
- What is the traffic source (this determines headline matching)?
Step 2: Select Copy Framework
| Framework | Best When | Audience Awareness Level |
|---|---|---|
| PAS (Problem > Agitate > Solve) | Audience knows the problem | Problem-aware |
| AIDA (Attention > Interest > Desire > Action) | Audience needs education | Unaware to problem-aware |
| BAB (Before > After > Bridge) | Audience wants transformation | Solution-aware |
Step 3: Build Sections in Order
| Order | Section | Purpose |
|---|---|---|
| 1 | Hero | Communicate value in 5 seconds |
| 2 | Social proof bar | Build instant credibility |
| 3 | Problem statement | Show you understand their pain |
| 4 | Solution / Benefits | Present your answer |
| 5 | How it works | Reduce perceived complexity |
| 6 | Features with benefits | Detail what they get |
| 7 | Testimonials | Proof from real customers |
| 8 | Pricing (if applicable) | Help them decide |
| 9 | FAQ | Handle objections |
| 10 | Final CTA | Repeat the ask with risk reversal |
Step 4: Write Copy Per Section
Use the section-specific guidelines in the Page Section Library below.
Step 5: Optimize for Conversion
Run the Conversion Optimization Checklist before launching.
Workflow 2: Campaign Landing Page
For ad campaigns, email campaigns, or launch events:
Step 1: Message Match
The landing page headline MUST match the ad/email that drives traffic:
- If ad says "Reduce churn by 30%," the landing page headline must say "Reduce churn by 30%"
- Mismatched expectations cause immediate bounce
Step 2: Single Message Focus
Remove all navigation, sidebar links, and secondary CTAs:
- No header navigation (removes exit paths)
- No footer links except legal requirements
- One CTA repeated 2-3 times on the page
- Every section supports the single conversion goal
Step 3: Traffic Source Adaptation
| Traffic Source | Page Adaptation |
|---|---|
| Paid search (Google) | Lead with the searched keyword in H1 |
| Paid social (Meta, LinkedIn) | Lead with the ad's hook/benefit |
| Email campaign | Lead with the email's promise |
| Organic search | Lead with the comprehensive answer |
| Referral/partner | Lead with the referrer's context |
---
Page Section Library
Hero Section
The most important section. Must communicate value in 5 seconds.
Components:
- Headline (primary value proposition)
- Subheadline (expand on headline, add specificity)
- Primary CTA button
- Secondary CTA (optional, lower commitment)
- Supporting visual (product screenshot, illustration, or video)
- Trust signal (social proof bar, customer count, or badge)
Hero Variants:
| Variant | Layout | Best For |
|---|---|---|
| Centered | Text centered, CTA below, visual below | Simple offers, clear value props |
| Split | Text left, visual right (or vice versa) | Product with strong visual/screenshot |
| Video background | Text overlay on ambient video | Brand-heavy, awareness pages |
| Minimal | Headline + CTA only, no visual | High-intent traffic, direct offers |
| Social proof hero | Testimonial as the headline | Strong customer story to lead with |
Hero Copy Guidelines:
- Headline: 6-12 words, includes the primary benefit
- Subheadline: 1-2 sentences, adds specificity or addresses the "how"
- CTA: Action verb + what they get ("Start my free trial")
- Supporting text below CTA: reduce friction ("No credit card required")
Problem Section
Make the reader feel understood before pitching anything.
Structure:
- 2-3 pain points in the reader's language
- Each pain point is specific and recognizable
- Optional: quantify the cost of the problem ("This costs teams an average of $X per month")
Solution / Benefits Section
Connect your product to the outcomes they want.
Structure:
- 3-5 key benefits (not features)
- Each benefit follows the pattern: [What it does] > [Why that matters] > [Specific outcome]
- Visual support for each benefit (icon, screenshot, or illustration)
How It Works Section
Reduce perceived complexity to 3-4 simple steps.
Structure:
- Step 1: [Action] (with brief description)
- Step 2: [Action] (with brief description)
- Step 3: [Action] (with brief description)
- Optional Step 4: [Outcome] ("See results within [timeframe]")
Rules:
- Never exceed 4 steps (complexity kills conversion)
- Each step starts with an action verb
- Each step can be understood independently
Social Proof Section
Types ranked by conversion impact:
| Type | Impact | Example |
|---|---|---|
| Named testimonial with metrics | Highest | "Reduced churn by 23% in 90 days" — Sarah Chen, VP Marketing |
| Customer logos | High | Row of recognizable brand logos |
| Aggregate metrics | High | "2,847 teams, 40+ countries, 4.8/5 rating" |
| Star ratings / review scores | Medium | "4.8 out of 5 on G2 (500+ reviews)" |
| Case study link | Medium | "See how [Company] achieved [result]" |
| Generic testimonial | Low | "Great product!" — John D. |
Pricing Section
Guidelines:
- 2-4 tiers maximum (3 is optimal)
- Highlight the recommended tier visually
- Feature comparison shows what is included in each tier
- Enterprise tier with "Contact us" for custom needs
- Annual vs. monthly toggle if offering both
- Trust signals near pricing (guarantee, cancel anytime)
FAQ Section
Guidelines:
- 5-8 questions maximum
- Questions should address real buying objections
- Answers should be direct (1-3 sentences)
- Include FAQPage schema markup for SEO
Common FAQ questions to include:
- How does pricing work?
- Can I cancel anytime?
- How long does setup take?
- Do you offer a free trial?
- Is my data secure?
- What integrations do you support?
- How is this different from [competitor]?
Final CTA Section
Structure:
- Headline restating the core value
- 1 sentence of supporting copy
- Primary CTA button (same as hero)
- Risk reversal statement (guarantee, no CC, cancel anytime)
- Optional: customer count or testimonial snippet
---
Copy Framework Application
PAS Application to Landing Page
| Section | PAS Element | Copy Approach |
|---|---|---|
| Hero headline | Problem | Name the pain directly |
| Problem section | Agitate | Show consequences of inaction |
| Solution section | Solve | Introduce product as the answer |
| CTA | Solve | Clear action to access the solution |
Example:
- Hero: "Your team wastes 4 hours every week on manual reporting"
- Problem: "That is 200 hours a year — the equivalent of losing a full-time employee to spreadsheets. Meanwhile, your competitors are shipping features."
- Solution: "[Product] automates your reporting. Set it once, get reports every Monday morning."
- CTA: "Automate my reports — start free trial"
AIDA Application to Landing Page
| Section | AIDA Element | Copy Approach |
|---|---|---|
| Hero headline | Attention | Bold, attention-grabbing statement |
| Benefits section | Interest | Expand with relevant details and benefits |
| Social proof | Desire | Show proof and paint the transformation |
| CTA | Action | Clear, compelling call to action |
BAB Application to Landing Page
| Section | BAB Element | Copy Approach |
|---|---|---|
| Hero + Problem | Before | Current painful state |
| Solution + Benefits | After | Desired future state |
| How it works | Bridge | How the product gets them there |
---
Conversion Optimization Checklist
Above the Fold
- [ ] Headline communicates value in under 6 seconds
- [ ] CTA is visible without scrolling on mobile (375px viewport)
- [ ] No more than one navigation option (or no navigation at all)
- [ ] Subheadline adds specificity to the headline
- [ ] Visual supports the message (not decorative)
Page-Wide
- [ ] Single conversion goal throughout the page
- [ ] CTA appears 2-3 times (hero, mid-page, footer)
- [ ] Social proof appears within the first two scrolls
- [ ] Every feature has a corresponding benefit
- [ ] Objections addressed before the final CTA
- [ ] Risk reversal stated near every CTA
- [ ] No external links that compete with the CTA
- [ ] Form asks for minimum required information
Trust and Credibility
- [ ] Customer testimonials are named and specific
- [ ] Company logos used with permission
- [ ] Security badges and certifications visible if relevant
- [ ] Privacy policy linked from any data collection form
- [ ] Physical address or company information available
Mobile
- [ ] Page loads under 3 seconds on mobile
- [ ] CTA button is thumb-friendly (minimum 48px height)
- [ ] Text is readable without zooming (16px minimum)
- [ ] No horizontal scrolling
- [ ] Forms are usable on mobile keyboards
---
Design Style Reference
Style Options
| Style | Visual Tone | Best For |
|---|---|---|
| Dark SaaS | Dark backgrounds, vibrant accents, gradient effects | Developer tools, technical products, modern SaaS |
| Clean Minimal | White backgrounds, subtle borders, clean typography | Professional services, healthcare, education |
| Bold Startup | Large typography, bright colors, dynamic layouts | Consumer products, startups, creative tools |
| Enterprise | Muted tones, structured layouts, conservative design | B2B enterprise, finance, government |
Visual Hierarchy Rules
1. Headline is the largest text element on the page 2. CTA button is the most visually prominent element 3. Supporting text is noticeably smaller than headlines 4. White space separates sections and creates breathing room 5. Color contrast meets WCAG AA standards (4.5:1 minimum for text) 6. Recommended plan on pricing pages is visually distinguished
---
CTA Strategy
CTA Placement
| Position | Purpose | Copy Approach |
|---|---|---|
| Hero | Primary conversion point | Action + benefit: "Start my free trial" |
| After benefits | Capture interest momentum | Reinforce: "See it in action" |
| After social proof | Capitalize on trust | Social: "Join 2,847 teams" |
| Page footer | Final catch | Urgency: "Start today — free for 14 days" |
CTA Copy Formulas
[Action Verb] + [What They Get]- "Start my free trial"
- "Get the complete guide"
- "See pricing for my team"
- "Create my first dashboard"
Supporting CTA Text
Below the button, reduce friction:
- "No credit card required"
- "Set up in 2 minutes"
- "Cancel anytime"
- "Free for 14 days"
- "Join 2,847 teams"
---
SEO and Performance
SEO Checklist
- [ ] Title tag: primary keyword + brand, 50-60 characters
- [ ] Meta description: benefit + CTA, 150-160 characters
- [ ] H1: one per page, includes primary keyword
- [ ] OG image: 1200x630px with product name and value proposition
- [ ] Canonical URL set
- [ ] Image alt text on all images
- [ ] Structured data: FAQPage schema if FAQ section exists
- [ ] Mobile viewport meta tag present
Performance Targets
| Metric | Target | How to Achieve |
|---|---|---|
| Largest Contentful Paint (LCP) | Under 2.5 seconds | Optimize hero image, use modern formats (WebP/AVIF) |
| Cumulative Layout Shift (CLS) | Under 0.1 | Set explicit dimensions on all images and embeds |
| First Input Delay (FID) | Under 100ms | Defer non-critical JavaScript |
| Time to First Byte (TTFB) | Under 600ms | Use CDN, server-side rendering, or static generation |
| Total page weight | Under 1MB | Compress images, minimize JavaScript bundles |
---
A/B Testing Framework
What to Test (Highest to Lowest Impact)
1. Headline — The single highest-impact element. Test 2-3 variants. 2. CTA copy and color — Test action text and visual prominence. 3. Hero image/visual — Product screenshot vs. illustration vs. video. 4. Social proof placement — Above fold vs. below benefits. 5. Form length — Fewer fields vs. more qualified leads. 6. Price display — Annual vs. monthly default, pricing anchor.
Testing Rules
- Test one variable at a time
- Run tests for minimum 14 days or 1,000 visitors per variant
- Calculate statistical significance (95% confidence) before declaring winner
- Document hypothesis, variants, and results for every test
- Never end a test early based on early results
Test Documentation
## A/B Test: [Name]
- Page: [URL]
- Hypothesis: [If we change X, then Y improves because Z]
- Control: [Current version]
- Variant: [Changed version]
- Primary metric: [Conversion rate / Click rate / Signup rate]
- Duration: [Start - End]
- Traffic per variant: [Number]
- Result: [Winner + lift + confidence]
- Learning: [What we apply going forward]---
Best Practices
1. One page, one goal — Every element on the page must serve the single conversion objective. If it does not help convert, remove it.
2. Match the message — The landing page headline must mirror the ad, email, or link that drove the visit. Mismatched expectations are the top bounce cause.
3. Remove navigation — Landing pages should have no header navigation, no sidebar, and no footer links except legal requirements. Every exit path is a lost conversion.
4. Mobile first — Design for 375px viewport first. The majority of ad traffic arrives on mobile devices.
5. Above-the-fold CTA — The primary CTA must be visible without scrolling on both desktop and mobile.
6. Social proof early — Place credibility signals within the first two scrolls. Trust is a prerequisite for conversion.
7. Minimize form fields — Every additional field reduces conversion. Ask for the minimum needed to qualify the lead.
8. Speed is conversion — Every second of load time reduces conversion rate by approximately 7%. Optimize aggressively.
9. Test relentlessly — The headline alone can produce 20-50% conversion differences. A/B test every high-impact element.
10. Risk reversal near every CTA — "No credit card required," "Money-back guarantee," "Cancel anytime." Remove the last objection at the moment of decision.
---
Integration Points
- Copywriting — Use for the copy layer. Landing Page Generator handles structure and optimization. Copywriting handles the words.
- Ad Creative — Use for the ads driving traffic to the landing page. Ensure message match between ad and page.
- Marketing Psychology — Use psychological principles (anchoring, social proof, loss aversion) to strengthen page elements.
- Campaign Analytics — Use to measure landing page performance and feed insights into optimization.
- Brand Guidelines — Reference brand visual and voice standards for consistency.
- Content Humanizer — Use if page copy sounds robotic or generic after initial drafting.
---
Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
| High bounce rate from paid traffic | Headline doesn't match the ad | Ensure exact message match between ad copy and landing page H1. |
| CTA below fold on mobile | Hero section too tall or CTA not prioritized | Test on 375px viewport. CTA must be visible without scrolling. |
| Good traffic but zero conversions | Conversion tracking broken | Verify pixel fires on thank-you page. Test with a real conversion. |
| Slow page load (>3s mobile) | Unoptimized images, heavy JS | Run page_speed_estimator.py. Convert images to WebP, defer non-critical JS. |
| Form submissions but no leads in CRM | Form-to-CRM integration broken | Test form submission end-to-end. Check webhook/API connection. |
| Multiple CTAs confusing visitors | Too many conversion paths | Single goal per landing page. All CTAs drive the same action. |
| Low conversion despite good copy | No social proof or risk reversal | Run conversion_checklist.py. Add testimonials and "no credit card" near CTAs. |
---
Success Criteria
- Conversion rate above 6.6% (2025 median across industries) for primary CTA
- Page loads under 3 seconds on mobile (LCP under 2.5s, CLS under 0.1)
- CTA visible above fold on both desktop (1440px) and mobile (375px)
- Single conversion goal with no competing navigation or exit paths
- Message match: landing page headline mirrors the traffic source (ad, email, link)
- Social proof visible within first two scrolls
- A/B test running on headline or CTA at all times for high-traffic pages
---
Scope & Limitations
In Scope: Landing page structure, section patterns, copy framework application, conversion optimization, CTA strategy, SEO meta tags, A/B testing framework, design style guidance.
Out of Scope: Page copy writing (use copywriting), paid ad campaigns driving traffic (use paid-ads), CMS/website builder administration, analytics platform setup.
Limitations: Conversion benchmarks vary significantly by industry, traffic source, and offer type. The 6.6% median is across all industries; SaaS trials may see 10-25% while e-commerce may see 2-3%.
---
Python Automation Tools
1. Page Speed Estimator (scripts/page_speed_estimator.py)
Estimates Core Web Vitals from HTML source: LCP, CLS risk, script/image analysis, and conversion impact.
python scripts/page_speed_estimator.py page.html
python scripts/page_speed_estimator.py page.html --json2. CTA Analyzer (scripts/cta_analyzer.py)
Analyzes CTA placement, copy strength, friction level, and consistency across the landing page.
python scripts/cta_analyzer.py page.html
python scripts/cta_analyzer.py page.html --json3. Conversion Checklist (scripts/conversion_checklist.py)
Runs a comprehensive 20+ point conversion optimization audit against 2025-2026 best practices and benchmarks.
python scripts/conversion_checklist.py page.html
python scripts/conversion_checklist.py page.html --json#!/usr/bin/env python3
"""
Landing Page Conversion Checklist
Runs a comprehensive conversion optimization audit on
landing page HTML against 2025-2026 best practices.
Usage:
python conversion_checklist.py page.html
python conversion_checklist.py page.html --json
"""
import argparse
import json
import re
import sys
from pathlib import Path
HTML_TAG = re.compile(r"<[^>]+>")
def audit_page(html: str) -> dict:
lower = html.lower()
plain = HTML_TAG.sub(" ", html)
plain = re.sub(r"\s+", " ", plain).strip()
checks = []
score = 0
max_score = 0
def check(name, condition, points, fail_msg):
nonlocal score, max_score
max_score += points
if condition:
score += points
checks.append({"name": name, "status": "PASS", "points": points})
else:
checks.append({"name": name, "status": "FAIL", "points": 0, "max_points": points, "fix": fail_msg})
# Above the Fold
check("H1 Tag Present", bool(re.search(r"<h1", lower)), 10, "Add a clear H1 headline")
check("Single H1", len(re.findall(r"<h1", lower)) <= 1, 5, "Use only one H1 per page")
check("CTA Button Present", bool(re.search(r"(btn|button|cta)", lower)), 10, "Add a prominent CTA button")
check("Subheadline Present", bool(re.search(r"<(h2|p class[^>]*sub)", lower)), 5, "Add a subheadline under H1")
# Navigation
has_nav = bool(re.search(r"<nav|<header[^>]*>.*<a", lower, re.DOTALL))
nav_link_count = len(re.findall(r"<nav.*?</nav>", lower, re.DOTALL))
check("Minimal Navigation", not has_nav or nav_link_count <= 1, 8, "Remove navigation -- landing pages should have no exit paths")
# Social Proof
check("Customer Logos", bool(re.search(r"(logo|customer|trusted.by|used.by|brand)", lower)), 8, "Add customer logos or 'Trusted by' section")
check("Testimonials", bool(re.search(r'(testimonial|review|".*".*[-—])', lower)), 8, "Add named testimonials with specific outcomes")
check("Numbers/Metrics", bool(re.search(r"\d+\s*(team|compan|customer|user|client)", plain, re.IGNORECASE)), 5, "Add specific customer counts or metrics")
# Trust & Credibility
check("Security Badges", bool(re.search(r"(soc.2|gdpr|iso|secure|encrypted|ssl|badge)", lower)), 5, "Add security badges if relevant")
check("Privacy Policy Link", bool(re.search(r"privacy", lower)), 3, "Link to privacy policy near forms")
# CTA Optimization
cta_count = len(re.findall(r"(btn|button|cta)", lower))
check("Multiple CTAs", cta_count >= 2, 8, "Place CTAs at hero, mid-page, and bottom")
check("Risk Reversal Near CTA", bool(re.search(r"(no credit card|cancel anytime|free trial|money.back|risk.free|guarantee)", lower)), 8, "Add risk reversal text near CTAs")
# Objection Handling
check("FAQ Section", bool(re.search(r"(faq|frequently|common question)", lower)), 5, "Add FAQ section to handle buying objections")
check("How It Works", bool(re.search(r"(how it works|step \d|3 steps|getting started)", lower)), 5, "Add 'How It Works' section (3-4 steps)")
# Mobile & Performance
check("Viewport Meta", bool(re.search(r'name\s*=\s*"viewport"', lower)), 5, "Add viewport meta tag for mobile")
check("Mobile-Friendly", bool(re.search(r"(responsive|mobile|@media)", lower)), 3, "Add responsive CSS/media queries")
images = re.findall(r"<img[^>]*>", html, re.IGNORECASE)
images_with_alt = len(re.findall(r'<img[^>]+alt\s*=\s*"[^"]+', html, re.IGNORECASE))
check("Image Alt Text", not images or images_with_alt >= len(images) * 0.8, 3, "Add alt text to all images")
# SEO
check("Title Tag", bool(re.search(r"<title[^>]*>.+</title>", lower)), 3, "Add a title tag with primary keyword")
check("Meta Description", bool(re.search(r'name\s*=\s*"description"', lower)), 3, "Add meta description with benefit + CTA")
check("OG Image", bool(re.search(r'property\s*=\s*"og:image"', lower)), 2, "Add Open Graph image for social sharing")
# Content Quality
word_count = len(plain.split())
check("Adequate Content", word_count >= 200, 3, "Page has very little content. Add more copy.")
check("Not Too Long", word_count <= 3000, 2, "Page is extremely long. Consider trimming.")
# Form optimization (if form exists)
has_form = bool(re.search(r"<form", lower))
if has_form:
inputs = re.findall(r"<input[^>]+type\s*=\s*\"(?!hidden|submit|button)", lower)
check("Form Fields < 5", len(inputs) <= 5, 5, f"Form has {len(inputs)} fields. Reduce to minimum required.")
pct = round(score / max(max_score, 1) * 100)
return {
"score": pct,
"points": f"{score}/{max_score}",
"grade": "A" if pct >= 85 else "B" if pct >= 70 else "C" if pct >= 55 else "D" if pct >= 40 else "F",
"checks": checks,
"passed": sum(1 for c in checks if c["status"] == "PASS"),
"failed": sum(1 for c in checks if c["status"] == "FAIL"),
"total_checks": len(checks),
"quick_wins": [c["fix"] for c in checks if c["status"] == "FAIL" and c.get("max_points", 0) >= 5][:5],
"benchmarks": {
"median_conversion_rate": "6.6% (all industries, 2025 data)",
"top_10_pct": ">10% conversion rate",
"page_load_target": "<3 seconds on mobile",
"note": "Every second of load time reduces conversion by ~7%",
},
}
def format_human(result: dict) -> str:
lines = ["\n" + "=" * 60, " LANDING PAGE CONVERSION CHECKLIST", "=" * 60]
lines.append(f"\n Score: {result['score']}% ({result['grade']}) | {result['passed']}/{result['total_checks']} checks passed")
lines.append(f"\n Checklist:")
for c in result["checks"]:
icon = "+" if c["status"] == "PASS" else "X"
fix = f" -- {c.get('fix', '')}" if c["status"] == "FAIL" else ""
lines.append(f" [{icon}] {c['name']}{fix}")
if result["quick_wins"]:
lines.append(f"\n Top Quick Wins:")
for i, qw in enumerate(result["quick_wins"], 1):
lines.append(f" {i}. {qw}")
b = result["benchmarks"]
lines.append(f"\n Benchmarks (2025-2026):")
lines.append(f" Median conversion: {b['median_conversion_rate']}")
lines.append(f" Top performers: {b['top_10_pct']}")
lines.append(f" Load target: {b['page_load_target']}")
lines.append(f" Note: {b['note']}")
lines.append("")
return "\n".join(lines)
def main():
parser = argparse.ArgumentParser(description="Run conversion optimization checklist on landing page.")
parser.add_argument("file", help="HTML file to audit")
parser.add_argument("--json", action="store_true", dest="json_output")
args = parser.parse_args()
try:
html = Path(args.file).read_text()
except FileNotFoundError:
print(f"Error: {args.file} not found", file=sys.stderr)
sys.exit(1)
result = audit_page(html)
if args.json_output:
print(json.dumps(result, indent=2))
else:
print(format_human(result))
if __name__ == "__main__":
main()
#!/usr/bin/env python3
"""
Landing Page CTA Analyzer
Analyzes CTA placement, copy strength, friction level,
and conversion optimization on landing pages.
Usage:
python cta_analyzer.py page.html
python cta_analyzer.py page.html --json
"""
import argparse
import json
import re
import sys
from pathlib import Path
BUTTON_PATTERN = re.compile(r'<(button|a)[^>]*(?:class\s*=\s*"[^"]*(?:btn|button|cta)[^"]*"|role\s*=\s*"button")[^>]*>(.*?)</\1>', re.IGNORECASE | re.DOTALL)
LINK_CTA_PATTERN = re.compile(r'<a[^>]+href[^>]*>(.*?)</a>', re.IGNORECASE | re.DOTALL)
HTML_TAG = re.compile(r"<[^>]+>")
STRONG_VERBS = {"start", "get", "create", "build", "try", "claim", "unlock", "discover", "join", "book", "download", "access"}
WEAK_VERBS = {"submit", "click", "send", "go", "enter", "continue"}
FRICTION_REDUCERS = ["no credit card", "free", "cancel anytime", "no commitment", "money-back", "risk-free", "2 minutes", "instant"]
def extract_ctas(html: str) -> list:
ctas = []
# Find buttons
for match in BUTTON_PATTERN.finditer(html):
text = HTML_TAG.sub("", match.group(2)).strip()
if text and len(text) < 60:
pos = match.start()
ctas.append({"text": text, "position_char": pos, "type": "button"})
# Find links that look like CTAs
for match in LINK_CTA_PATTERN.finditer(html):
text = HTML_TAG.sub("", match.group(1)).strip()
tag = match.group(0).lower()
if text and len(text) < 60 and any(kw in tag for kw in ["btn", "button", "cta", "trial", "demo", "signup", "start"]):
pos = match.start()
ctas.append({"text": text, "position_char": pos, "type": "link"})
return ctas
def analyze_cta(cta_text: str) -> dict:
lower = cta_text.lower()
words = lower.split()
first_word = words[0] if words else ""
strength = "moderate"
if first_word in STRONG_VERBS:
strength = "strong"
elif first_word in WEAK_VERBS:
strength = "weak"
has_ownership = any(w in words for w in ["my", "your"])
has_benefit = len(words) > 2
score = 50
if strength == "strong":
score += 25
elif strength == "weak":
score -= 15
if has_ownership:
score += 10
if has_benefit:
score += 15
return {
"text": cta_text,
"strength": strength,
"has_ownership_language": has_ownership,
"describes_what_you_get": has_benefit,
"word_count": len(words),
"score": min(100, max(0, score)),
}
def analyze_page(html: str) -> dict:
html_length = len(html)
ctas = extract_ctas(html)
# Check for friction reducers near CTAs
lower_html = html.lower()
friction_found = [f for f in FRICTION_REDUCERS if f in lower_html]
# Estimate CTA positions (early = above fold, middle, late)
cta_analyses = []
for cta in ctas:
position_pct = (cta["position_char"] / html_length * 100) if html_length > 0 else 0
zone = "above_fold" if position_pct < 20 else "mid_page" if position_pct < 60 else "bottom"
analysis = analyze_cta(cta["text"])
analysis["zone"] = zone
analysis["position_pct"] = round(position_pct, 1)
cta_analyses.append(analysis)
# Scoring
issues = []
recommendations = []
score = 50
# CTA count
if len(ctas) == 0:
issues.append("No CTAs found on the page.")
score -= 30
elif len(ctas) == 1:
issues.append("Only 1 CTA. Best practice: 2-3 CTAs throughout the page.")
score -= 10
elif 2 <= len(ctas) <= 4:
score += 15
else:
recommendations.append(f"{len(ctas)} CTAs found -- ensure they don't compete. All should drive the same action.")
# Above fold CTA
above_fold = [c for c in cta_analyses if c["zone"] == "above_fold"]
if above_fold:
score += 15
else:
issues.append("No CTA above the fold. Primary CTA must be visible without scrolling.")
score -= 15
# CTA consistency
cta_texts = [c["text"].lower() for c in cta_analyses]
unique_texts = set(cta_texts)
if len(unique_texts) > 2 and len(ctas) > 1:
issues.append(f"{len(unique_texts)} different CTA texts. Use consistent CTAs driving one action.")
score -= 10
# Friction reducers
if friction_found:
score += 10
recommendations.append(f"Good: Friction reducers detected: {', '.join(friction_found)}")
else:
recommendations.append("Add friction reducers near CTAs: 'No credit card required', 'Free for 14 days', etc.")
score -= 5
# CTA strength
strong_ctas = [c for c in cta_analyses if c["strength"] == "strong"]
weak_ctas = [c for c in cta_analyses if c["strength"] == "weak"]
if weak_ctas:
recommendations.append(f"Strengthen weak CTAs: {', '.join([c['text'] for c in weak_ctas][:3])}")
score = max(0, min(100, score))
return {
"total_ctas": len(ctas),
"score": score,
"grade": "A" if score >= 85 else "B" if score >= 70 else "C" if score >= 55 else "D" if score >= 40 else "F",
"ctas": cta_analyses,
"friction_reducers_found": friction_found,
"placement": {
"above_fold": len(above_fold),
"mid_page": len([c for c in cta_analyses if c["zone"] == "mid_page"]),
"bottom": len([c for c in cta_analyses if c["zone"] == "bottom"]),
},
"issues": issues,
"recommendations": recommendations,
}
def format_human(result: dict) -> str:
lines = ["\n" + "=" * 55, " LANDING PAGE CTA ANALYZER", "=" * 55]
lines.append(f"\n Score: {result['score']}/100 ({result['grade']}) | CTAs Found: {result['total_ctas']}")
p = result["placement"]
lines.append(f" Placement: Above-fold: {p['above_fold']} | Mid-page: {p['mid_page']} | Bottom: {p['bottom']}")
if result["ctas"]:
lines.append(f"\n CTA Analysis:")
for c in result["ctas"]:
lines.append(f" \"{c['text']}\" | {c['strength']} | {c['zone']} ({c['position_pct']}%) | Score: {c['score']}")
if result["issues"]:
lines.append(f"\n Issues:")
for i in result["issues"]:
lines.append(f" ! {i}")
lines.append(f"\n Recommendations:")
for r in result["recommendations"]:
lines.append(f" > {r}")
lines.append("")
return "\n".join(lines)
def main():
parser = argparse.ArgumentParser(description="Analyze CTA placement and quality on landing pages.")
parser.add_argument("file", help="HTML file")
parser.add_argument("--json", action="store_true", dest="json_output")
args = parser.parse_args()
try:
html = Path(args.file).read_text()
except FileNotFoundError:
print(f"Error: {args.file} not found", file=sys.stderr)
sys.exit(1)
result = analyze_page(html)
if args.json_output:
print(json.dumps(result, indent=2))
else:
print(format_human(result))
if __name__ == "__main__":
main()
#!/usr/bin/env python3
"""
Landing Page Speed Estimator
Estimates page load performance from HTML source, checking
against Core Web Vitals targets and conversion benchmarks.
Usage:
python page_speed_estimator.py page.html
python page_speed_estimator.py page.html --json
"""
import argparse
import json
import re
import sys
from pathlib import Path
CWV_TARGETS = {
"lcp": {"good": 2.5, "needs_improvement": 4.0, "unit": "seconds"},
"cls": {"good": 0.1, "needs_improvement": 0.25, "unit": "score"},
"fid": {"good": 100, "needs_improvement": 300, "unit": "ms"},
"ttfb": {"good": 600, "needs_improvement": 1200, "unit": "ms"},
}
def estimate_speed(html: str) -> dict:
size_bytes = len(html.encode("utf-8"))
size_kb = size_bytes / 1024
# Count resources
scripts = re.findall(r"<script[^>]*(?:src|>)", html, re.IGNORECASE)
external_scripts = [s for s in scripts if 'src=' in s.lower()]
inline_scripts = [s for s in scripts if 'src=' not in s.lower()]
stylesheets = re.findall(r'<link[^>]+rel\s*=\s*"stylesheet"', html, re.IGNORECASE)
images = re.findall(r"<img[^>]+>", html, re.IGNORECASE)
videos = re.findall(r"<video[^>]+>", html, re.IGNORECASE)
iframes = re.findall(r"<iframe[^>]+>", html, re.IGNORECASE)
fonts = re.findall(r"font-family|@font-face|fonts\.googleapis", html, re.IGNORECASE)
# Check for optimization patterns
has_lazy_loading = bool(re.search(r'loading\s*=\s*"lazy"', html, re.IGNORECASE))
has_async_scripts = bool(re.search(r'<script[^>]+async', html, re.IGNORECASE))
has_defer_scripts = bool(re.search(r'<script[^>]+defer', html, re.IGNORECASE))
has_preload = bool(re.search(r'rel\s*=\s*"preload"', html, re.IGNORECASE))
has_webp_avif = bool(re.search(r'\.(webp|avif)', html, re.IGNORECASE))
has_srcset = bool(re.search(r'srcset\s*=', html, re.IGNORECASE))
has_viewport = bool(re.search(r'name\s*=\s*"viewport"', html, re.IGNORECASE))
images_with_dims = len(re.findall(r'<img[^>]+width[^>]+height', html, re.IGNORECASE))
# Estimate LCP (rough)
lcp_estimate = 1.0 # base
lcp_estimate += size_kb / 200 # page size impact
lcp_estimate += len(external_scripts) * 0.15 # render blocking
lcp_estimate += len(stylesheets) * 0.1
lcp_estimate += len(images) * 0.08
if not has_async_scripts and not has_defer_scripts and external_scripts:
lcp_estimate += 0.5
if not has_webp_avif and images:
lcp_estimate += 0.3
if has_preload:
lcp_estimate -= 0.2
# CLS risk
cls_risk = 0.0
images_without_dims = len(images) - images_with_dims
cls_risk += images_without_dims * 0.03
if iframes:
cls_risk += len(iframes) * 0.05
if not has_viewport:
cls_risk += 0.1
# Build report
checks = []
# Page weight
if size_kb < 500:
checks.append({"name": "Page Weight", "status": "PASS", "detail": f"{size_kb:.0f}KB (target: <1MB)"})
elif size_kb < 1024:
checks.append({"name": "Page Weight", "status": "WARN", "detail": f"{size_kb:.0f}KB"})
else:
checks.append({"name": "Page Weight", "status": "FAIL", "detail": f"{size_kb:.0f}KB (>1MB)"})
# Scripts
if len(external_scripts) <= 3:
checks.append({"name": "External Scripts", "status": "PASS", "detail": f"{len(external_scripts)} scripts"})
else:
checks.append({"name": "External Scripts", "status": "WARN", "detail": f"{len(external_scripts)} scripts -- reduce render-blocking JS"})
if external_scripts and (has_async_scripts or has_defer_scripts):
checks.append({"name": "Script Loading", "status": "PASS", "detail": "async/defer detected"})
elif external_scripts:
checks.append({"name": "Script Loading", "status": "WARN", "detail": "No async/defer on scripts"})
# Images
if images and has_lazy_loading:
checks.append({"name": "Lazy Loading", "status": "PASS", "detail": "Lazy loading detected"})
elif images:
checks.append({"name": "Lazy Loading", "status": "WARN", "detail": "No lazy loading on images"})
if images and has_webp_avif:
checks.append({"name": "Modern Image Formats", "status": "PASS", "detail": "WebP/AVIF detected"})
elif images:
checks.append({"name": "Modern Image Formats", "status": "WARN", "detail": "Use WebP/AVIF for 25-50% size reduction"})
if images_without_dims > 0:
checks.append({"name": "Image Dimensions", "status": "WARN", "detail": f"{images_without_dims} images missing width/height (causes CLS)"})
# CWV estimates
lcp_status = "PASS" if lcp_estimate <= CWV_TARGETS["lcp"]["good"] else "WARN" if lcp_estimate <= CWV_TARGETS["lcp"]["needs_improvement"] else "FAIL"
cls_status = "PASS" if cls_risk <= CWV_TARGETS["cls"]["good"] else "WARN" if cls_risk <= CWV_TARGETS["cls"]["needs_improvement"] else "FAIL"
checks.append({"name": "Est. LCP", "status": lcp_status, "detail": f"~{lcp_estimate:.1f}s (target: <2.5s)"})
checks.append({"name": "Est. CLS Risk", "status": cls_status, "detail": f"~{cls_risk:.2f} (target: <0.1)"})
# Conversion impact
conversion_impact = []
if lcp_estimate > 3:
lost_pct = round((lcp_estimate - 1) * 7)
conversion_impact.append(f"~{lost_pct}% potential conversion loss from slow load time")
if not has_viewport:
conversion_impact.append("Missing viewport meta -- mobile users will have poor experience")
recs = []
if not has_async_scripts and external_scripts:
recs.append("Add async or defer to non-critical scripts.")
if not has_lazy_loading and images:
recs.append("Add loading='lazy' to below-fold images.")
if not has_webp_avif and images:
recs.append("Convert images to WebP/AVIF format (25-50% smaller).")
if images_without_dims > 0:
recs.append("Add explicit width and height to all images to prevent CLS.")
if not has_preload:
recs.append("Add rel='preload' for critical resources (hero image, main font).")
if size_kb > 1024:
recs.append("Reduce page weight below 1MB. Compress images and minify CSS/JS.")
if not recs:
recs.append("Page looks well-optimized. Monitor CWV in Google Search Console for real-user data.")
# Score
score = 100
for c in checks:
if c["status"] == "WARN":
score -= 8
elif c["status"] == "FAIL":
score -= 15
score = max(0, min(100, score))
return {
"page_size_kb": round(size_kb, 1),
"score": score,
"grade": "A" if score >= 85 else "B" if score >= 70 else "C" if score >= 55 else "D" if score >= 40 else "F",
"resource_counts": {
"external_scripts": len(external_scripts),
"inline_scripts": len(inline_scripts),
"stylesheets": len(stylesheets),
"images": len(images),
"videos": len(videos),
"iframes": len(iframes),
"fonts": len(fonts),
},
"cwv_estimates": {
"lcp_seconds": round(lcp_estimate, 1),
"cls_risk": round(cls_risk, 2),
},
"checks": checks,
"conversion_impact": conversion_impact,
"recommendations": recs,
}
def format_human(result: dict) -> str:
lines = ["\n" + "=" * 55, " LANDING PAGE SPEED ESTIMATOR", "=" * 55]
lines.append(f"\n Score: {result['score']}/100 ({result['grade']}) | Size: {result['page_size_kb']}KB")
r = result["resource_counts"]
lines.append(f" Scripts: {r['external_scripts']}ext/{r['inline_scripts']}inline | CSS: {r['stylesheets']} | Images: {r['images']}")
cwv = result["cwv_estimates"]
lines.append(f"\n Core Web Vitals Estimates:")
lines.append(f" LCP: ~{cwv['lcp_seconds']}s (target: <2.5s)")
lines.append(f" CLS Risk: ~{cwv['cls_risk']} (target: <0.1)")
lines.append(f"\n Checks:")
for c in result["checks"]:
icon = {"PASS": "+", "WARN": "!", "FAIL": "X"}
lines.append(f" [{icon.get(c['status'], '?')}] {c['name']}: {c['detail']}")
if result["conversion_impact"]:
lines.append(f"\n Conversion Impact:")
for ci in result["conversion_impact"]:
lines.append(f" !! {ci}")
lines.append(f"\n Recommendations:")
for rec in result["recommendations"]:
lines.append(f" > {rec}")
lines.append("")
return "\n".join(lines)
def main():
parser = argparse.ArgumentParser(description="Estimate landing page speed and Core Web Vitals.")
parser.add_argument("file", help="HTML file to analyze")
parser.add_argument("--json", action="store_true", dest="json_output")
args = parser.parse_args()
try:
html = Path(args.file).read_text()
except FileNotFoundError:
print(f"Error: {args.file} not found", file=sys.stderr)
sys.exit(1)
result = estimate_speed(html)
if args.json_output:
print(json.dumps(result, indent=2))
else:
print(format_human(result))
if __name__ == "__main__":
main()
Related skills
FAQ
Which copy frameworks does it use?
PAS (Problem-Agitate-Solve), AIDA (Attention-Interest-Desire-Action), and BAB (Before-After-Bridge), chosen by audience awareness level.
What section order does it recommend?
Hero, social proof bar, problem, solution/benefits, how it works, features, testimonials, pricing, FAQ, then final CTA.