# Build a competitor comparison landing page: runbook for agents

Give this file to your agent (Claude Code, Cursor, or anything that can read a
URL). It is the executable version of
https://adside.ai/blog/competitor-comparison-landing-pages: what to collect,
what to research, the page and campaign specs as data, the prompts verbatim,
and a checklist that says when you are done.

**Division of labor.** The agent researches the competitor, writes the claims
ledger, writes the copy, builds the page and the campaign spec, and runs every
check in section 8. The human supplies the inputs in section 1. The person who
owns the legal risk (for agency work, the client's marketing or legal contact,
not just whoever is running the agent) approves the claims ledger before any
copy is written, approves the page before it goes live, and approves the
campaign before it spends. The agent never publishes a page or creates or
enables a campaign on its own.

Source: https://adside.ai/blog/competitor-comparison-landing-pages
Last updated: 2026-09-14

---

## 0. Outcome (definition of done)

Four artifacts, delivered together:

1. **A claims ledger** (section 4): every statement the page makes about the
   competitor, with the source URL and the capture date, approved by the human.
2. **One landing page** at a URL like `/lp/{competitor-slug}-alternative` or
   `/lp/{you}-vs-{competitor-slug}`, built from the human's site kit, that:
   - names the competitor in the H1 or the line under it,
   - has no site navigation (logo + one button; legal links in the footer),
   - contains one comparison table of 6 to 10 rows with at least one row the
     competitor wins or ties,
   - shows pricing for both products with a capture date, or says "not public",
   - carries a plain-text "not affiliated" trademark line,
   - has one call to action,
   - is `noindex`, passes click IDs through, and loads in under 2 seconds on
     a phone.
3. **A campaign spec** (section 7): keywords, match types, negative keywords,
   ad copy that never uses the competitor's mark, and the tracking plan.
4. **A QA report**: the checklist in section 8 with every line ticked or
   explained.

If any of the four is missing, the job is not finished.

---

## 1. Inputs to collect from the human before starting

Ask for these once, up front. Do not research or write until you have the
first four.

| Input | Format | Why it matters |
|---|---|---|
| Your product | Name, URL, one sentence on what it is and who it's for | The page's half of the "who each is for" pair |
| Competitor | Name, URL | Everything in section 2 keys off this |
| Query intent | One of `alternative`, `vs`, `pricing` | Decides the headline, the opening and the order of sections (section 3.1) |
| Region | `US`, `EU`, `UK` or a list | Decides which legal rules in section 3.3 apply |
| Site kit (optional) | Logo SVG, font files, hex colors with roles, button styles, footer legal links; if the human has none, the live site URL is enough (section 6 extracts them) | The page must look like the site, not like a template |
| Codebase and deploy target | Repo URL, framework, how preview and production deploys work, or "standalone HTML file" | Decides whether the agent can ship the page on the real domain or only hand over a file |
| Features that decide the purchase | 6 to 10 rows, in the buyer's words | The table. Ask the human which row they'd concede; if they can't name one, you will find one in 2.6 |
| Your pricing | Public plans and prices, or "not public" | Transparent pricing produces fewer but better leads; never invent a number |
| Switching offer | Free migration, credit against the competitor's remaining contract, no-card trial, or none | The reason "alternative" searchers convert |
| Switcher proof | 1 to 3 quotes from customers who moved from the competitor, with name, role, company and written permission | Testimonials are regulated (section 3.3); no permission, no quote |
| CTA | `demo` or `trial`, and the real destination URL | One button, the right one for the sales motion |
| Tracking | Conversion action, click-ID parameter (`gclid`), CRM field that receives it | The campaign is judged on qualified pipeline, not form fills |

---

## 2. Research (the agent does this)

Record every fact as a row in the claims ledger (section 4) as you go. A fact
without a URL and a capture date does not go on the page.

2.1 **Competitor positioning.** Fetch their homepage. Capture the H1, the
subhead and the primary CTA. Write the two-sentence "who it's for" summary in
words their own marketing team would sign off on.

2.2 **Competitor pricing.** Fetch their pricing page. Record each public plan
with its price, billing period and the units (per seat, per month, per
credit). If pricing is not public, record "not public" and say so on the page.
Never estimate.

2.3 **Review scores.** Fetch the public G2 and Capterra pages for both
products. Record the score, the review count and the date. If the competitor
scores higher, that is a row they win; use it. Both sites block plain fetches
some of the time: if you get a challenge page or an empty shell, ask the human
to paste the score, the count and the URL, or drop the row. Never estimate.

2.4 **Feature verification.** For each of the 6 to 10 rows, find the
competitor's own documentation or help center page that confirms or denies the
feature. Mark each row `win`, `tie` or `lose` from your product's point of
view. A row you cannot verify on the competitor's own site is `unknown` and
does not go in the table.

2.5 **Their ads.** Search the competitor in the Google Ads Transparency Center
(https://adstransparency.google.com). It is a client-rendered app, so this step
needs a browser tool (Playwright, a browser MCP) rather than a plain URL fetch;
without one, ask the human whether the competitor runs ads on its own name and
whether it already has a "vs you" page. If such a page exists, read it and make
sure your table doesn't contradict a fact they can prove.

2.6 **The concession.** If steps 2.3 and 2.4 produced no row the competitor
wins or ties, keep looking until one exists: integration count, ecosystem size,
years in market, a lower entry price, a free tier, a mobile app. A table with
no concession is a page nobody trusts, and in the UK it is a page the
regulator has already banned once (section 9, ASA ruling).

2.7 **Query check.** Search `{competitor} alternative`, `{competitor} vs {you}`
and `{competitor} pricing`. Note which pages rank and whether rival ads appear.
This tells you which intent the page should serve first and what the searcher
has already read.

---

## 3. Specs (data)

### 3.1 Page structure

Order for `alternative` intent. For `vs` intent, move the table directly under
the hero. For `pricing` intent, move the pricing section directly under the
hero.

| # | Section | Content | Limits |
|---|---|---|---|
| 1 | Header | Logo, one button (the CTA). No menu, no login link, no banner | |
| 2 | Hero | H1 names the competitor and states the reason to switch. Sub-line: two sentences, one per product, saying who each is for | H1 ≤ 12 words. Sub-line ≤ 45 words |
| 3 | Proof strip | 3 to 5 facts about your product with sources (customers, rating, uptime, time to go live) or a logo row of your customers | Your numbers only, each sourced |
| 4 | Switcher quote | One quote from a customer who moved from the competitor, with name, role, company | Verbatim, permission on file |
| 5 | Comparison table | 6 to 10 rows. Columns: feature, you, competitor. Cells are short text, not only icons. At least one row the competitor wins or ties | Every competitor cell traceable to a ledger row |
| 6 | Pricing | Both products' public pricing with the capture date. If the competitor's pricing is not public, say "not public" | No estimates, no "from" prices without the plan name |
| 7 | Switching offer | What you give someone who moves, and how long it takes | One paragraph |
| 8 | Deep dives | 2 or 3 short sections on the rows you win by the most, with your own screenshots only | ≤ 120 words each |
| 9 | CTA | One button, same as the header, with one line under it that removes the last objection | |
| 10 | Footer | Legal links, privacy, and the trademark line | |

Word budget for the whole page: 300 to 800 words. Longer than that is an SEO
page, and this is not one.

### 3.2 Copy rules

- Full sentences, contractions, plain language. No triads ("faster, smarter,
  better"). No em dashes.
- The competitor's name appears as plain text only. No logo, no product
  screenshots, no brand colors, no stylized wordmark.
- No superlatives ("best", "#1", "leading") unless the page links to the
  study that says so.
- No disparagement. Banned words about the competitor: `scam`, `dying`,
  `outdated`, `legacy`, `bloated`, `abandoned`, `nobody`, `everyone knows`.
- Cells in the table state facts, not opinions. "Reply within 24 hours on all
  plans" is a fact. "You're a ticket number" is an opinion and does not go in
  a table.
- Every number on the page about the competitor is in the ledger with a URL
  and a date. Every number about your product is one the human confirmed.
- Say who the competitor is good for. If the two-sentence summary would make
  their team wince, rewrite it.

### 3.3 Legal and platform rules

| Rule | Where it applies | What to do |
|---|---|---|
| Bidding on a competitor's trademark as a keyword is allowed | Google Ads, all regions | Bid. Use exact and phrase match only |
| The competitor's mark cannot appear in ad text or display URL once the owner complains | Google Ads, all regions | Write ads without the name from day one ("The alternative", "Switch now"); do not put the name in the display path |
| Landing pages are judged on destination and misrepresentation policies, not the trademark policy | Google Ads | The page may name the competitor. It may not imply affiliation, and the display URL domain must match the final URL domain |
| Nominative fair use: name only, as much as needed, no implied endorsement | US | Plain text, no logo, plus the trademark line |
| Truthful comparative advertising is encouraged; claims need the same substantiation as any ad claim | US (FTC) | The ledger is the substantiation |
| Testimonials must be genuine and not edited to change meaning; insider reviews disclosed | US (FTC Consumer Reviews and Testimonials Rule, in force since October 21, 2024) | Verbatim quotes with permission on file |
| Comparison must be objective, on material and verifiable features, must not denigrate or trade on the competitor's reputation | EU (Directive 2006/114/EC Art. 4), UK (CAP Code 3.33 to 3.35) | The table, the concession row and the ledger cover this. No opinion cells |
| A table that marks a feature with a cross when the competitor has it is misleading | UK (ASA ruling, February 2026), and good practice everywhere | Step 2.4: no `unknown` rows in the table |

Trademark line, verbatim, at the bottom of the page:

> {Competitor} is a trademark of {Competitor legal entity, if known, else "its
> respective owner"}. {You} is not affiliated with or endorsed by {Competitor}.
> Comparison data captured on {date}; sources listed on request.

### 3.4 Technical

| Item | Value |
|---|---|
| `<meta name="robots">` | `noindex` (not `nofollow`: the CTA link should still be followed) |
| Canonical | The page's own URL |
| Navigation | None. Header is logo + one CTA button |
| Footer | Legal links and the trademark line only |
| Fonts, colors, buttons | From the site kit. No substitutes |
| Click ID | Read `gclid` and `utm_*` from the URL, append them to the CTA link, and store `gclid` in a hidden form field or first-party cookie |
| Performance | Largest Contentful Paint under 2.5 s on a mid-range phone; no third-party scripts beyond analytics and the conversion tag |
| Images | Your own product only, compressed, lazy-loaded below the fold |
| Schema | None required |

### 3.5 Machine-readable spec

```json
{
  "page": {
    "url_pattern": { "alternative": "/lp/{competitor-slug}-alternative", "vs": "/lp/{you-slug}-vs-{competitor-slug}", "pricing": "/lp/{competitor-slug}-pricing" },
    "robots": "noindex",
    "nav": "logo + one CTA",
    "word_budget": [300, 800],
    "sections": ["header", "hero", "proof", "switcher_quote", "table", "pricing", "offer", "deep_dives", "cta", "footer"],
    "h1_max_words": 12,
    "table": { "rows_min": 6, "rows_max": 10, "competitor_wins_or_ties_min": 1, "cells": "short text, not icons only" },
    "pricing": { "both_products": true, "capture_date_required": true, "estimates_allowed": false },
    "competitor_brand_assets_allowed": false,
    "trademark_line_required": true,
    "banned_words": ["scam", "dying", "outdated", "legacy", "bloated", "abandoned", "nobody", "everyone knows"],
    "em_dashes_allowed": false
  },
  "campaign": {
    "keywords": ["{competitor}", "{competitor} alternative", "{competitor} vs {you}", "{competitor} pricing", "{competitor} reviews"],
    "match_types": ["exact", "phrase"],
    "negatives": ["login", "log in", "sign in", "support", "help", "docs", "documentation", "api", "status", "careers", "jobs", "tutorial", "training", "certification", "free", "free download", "coupon", "discount", "promo code", "crack"],
    "negatives_note": "exact match expands to close variants; review the search terms report weekly and keep adding",
    "ad_text_may_include_competitor_mark": false,
    "display_path_may_include_competitor_mark": false,
    "ad_groups": { "one_per_intent": true, "fallback_if_single_page": "route alternative and vs to it; pause brand until a second variant exists", "pricing_negative_on_other_groups": true },
    "final_url_params": "utm_source=google&utm_medium=cpc&utm_campaign=comp-{competitor-slug}&utm_term={keyword}",
    "evaluation_window_days": [60, 90],
    "success_metric": "cost per qualified opportunity"
  }
}
```

---

## 4. Step 1: the claims ledger

Produce this table before writing a word of copy, and get the human's
approval on it. One row per fact about the competitor.

| # | Claim as it will appear on the page | Type | Source URL | Captured (ISO date) | Verdict |
|---|---|---|---|---|---|
| 1 | "{Competitor} Growth plan is $47/month billed annually" | price | https://… | 2026-09-14 | win / tie / lose |
| 2 | "{Competitor} does not offer native voice calls" | feature | https://… (their docs) | 2026-09-14 | win |
| 3 | "{Competitor} scores 4.8 on G2 from 1,240 reviews" | review | https://… | 2026-09-14 | lose |

Rules: no row without a URL on the competitor's own domain or a public review
site. A price older than 90 days at publish time gets re-fetched. Rows marked
`unknown` are deleted, not softened.

---

## 5. Step 2: write the copy

Paste this as one message to the model that writes the copy, with the inputs
and the approved ledger attached:

```
Write the copy for a paid-traffic landing page for {you} aimed at people who
searched "{competitor} {intent}" on Google and clicked our ad.

Inputs: {paste section 1 inputs}. Approved claims ledger: {paste section 4 table}.

Structure, in this order: H1 (≤12 words, names {competitor}, states the reason
to switch); sub-line (two sentences: who {competitor} is for, who {you} is for,
written so {competitor}'s team would agree with theirs); proof strip (3 to 5
sourced facts about {you}); one switcher quote (verbatim from inputs);
comparison table (6 to 10 rows from the ledger, columns feature / {you} /
{competitor}, short text cells, include every row marked lose or tie);
pricing (both products, capture date, "not public" if so); switching offer
(one paragraph); 2 or 3 deep dives (≤120 words each, on the rows we win by the
most); CTA line (one sentence that removes the last objection); trademark line.

Rules: full sentences, contractions, plain language. No triads. No em dashes.
{competitor} in plain text only. No superlatives without a linked source. No
opinions in table cells. Do not use these words about {competitor}: scam,
dying, outdated, legacy, bloated, abandoned, nobody, everyone knows. Do not
invent a number: every figure about {competitor} must match a ledger row, and
every figure about {you} must be in the inputs. Total length 400 to 900 words.

Output as JSON with keys: h1, subline, proof[], quote{text,name,role,company},
table[{feature, you, competitor, verdict, ledger_row}], pricing{you, competitor,
captured}, offer, deep_dives[{title, body}], cta{button, line}, trademark_line.
```

Read the output aloud as if to someone who works at the competitor. If a line
would make them feel attacked rather than fairly described, rewrite it.

---

## 6. Step 3: build the page

Build from the human's site kit. If the site has a design system or component
library, use it; if not, extract the header, buttons, type and colors from
their live site and reuse them. The page should be indistinguishable from the
rest of the site at a glance, minus the menu.

Minimum semantic structure:

```html
<head>
  <meta name="robots" content="noindex">
  <link rel="canonical" href="https://{your-domain}/lp/{competitor-slug}-alternative">
  <title>{H1} | {You}</title>
</head>
<body>
  <header><!-- logo linked to /, one CTA button --></header>
  <main>
    <section id="hero"><h1>…</h1><p>…</p><a class="cta" href="{cta_url}">…</a></section>
    <section id="proof">…</section>
    <blockquote id="switcher">…</blockquote>
    <section id="compare"><table><!-- feature / you / competitor --></table></section>
    <section id="pricing">…<small>Captured {date}</small></section>
    <section id="offer">…</section>
    <section id="deep-dives">…</section>
    <section id="cta">…</section>
  </main>
  <footer><!-- legal links, trademark line --></footer>
  <script>/* read gclid + utm_* from location.search, append to every .cta href, store gclid in a first-party cookie */</script>
</body>
```

Then render it at 390 px and 1440 px wide and look at both. This needs a
screenshot tool (Playwright, a browser MCP); without one, hand the human the
two URLs and ask them to confirm. The H1, the sub-line and the CTA must be
visible without scrolling at 390 px. Put the page next to the site's homepage:
header, type, colors and buttons should match closely enough that someone who
knows the site wouldn't notice the switch.

---

## 7. Step 4: the campaign

- **Campaign:** one per competitor, search only, no display expansion, no
  broad match, no Performance Max.
- **Ad groups:** one per intent (`brand`, `alternative`, `vs`, `pricing`),
  each pointing at the page variant whose headline mirrors that intent. If
  only one page exists, send `alternative` and `vs` to it and pause `brand`
  until a second variant is built.
- **Keywords:** `[{competitor}]`, `"{competitor} alternative"`,
  `"{competitor} vs {you}"`, `"{competitor} pricing"`, `"{competitor} reviews"`.
  Exact and phrase only. Exact match still expands to close variants
  (misspellings, reorderings, same-intent phrases), so read the search terms
  report weekly and keep adding negatives.
- **Negatives:** the list in section 3.5, plus the competitor's product names
  that you don't compete with. If a pricing ad group exists, add
  `"{competitor} pricing"` as a negative on the alternative and vs ad groups so
  they don't compete with it.
- **If a trademark complaint arrives:** Google will disapprove the ads that
  carry the mark. Swap to the no-mark ad copy variant within 24 hours, tell the
  human, and log the complaint and the date in the claims ledger. The landing
  page can keep the competitor's name.
- **Ad copy:** never the competitor's name in headlines, descriptions or the
  display path. Headline patterns that survive a trademark complaint:
  "The {category} alternative", "Switch in {n} days", "{Your one-line
  positioning}", "Free migration from your current tool". Say "alternative"
  in the ad; let the page say the name.
- **Tracking:** final URL carries `utm_term={keyword}` and the campaign name;
  `gclid` reaches the CRM opportunity record. Import offline conversions
  (qualified, closed-won) back into Google Ads.
- **Evaluation:** 60 to 90 days of clean data before judging. The metric is
  cost per qualified opportunity, not CTR, not cost per form fill. Expect lower
  CTR than on your own brand terms; that is normal on a competitor search.

---

## 8. Acceptance checklist

- [ ] Claims ledger exists, every row has a URL on the competitor's domain or a public review site and an ISO capture date, and the human approved it.
- [ ] H1 or the line under it names the competitor; sub-line says who each product is for in a way the competitor would accept.
- [ ] No site navigation. Header is logo + one button. Footer is legal links + trademark line.
- [ ] Table has 6 to 10 rows, short text cells, and at least one row marked lose or tie. No `unknown` rows.
- [ ] Pricing shown for both products with a capture date, or "not public" stated.
- [ ] No competitor logo, screenshots, colors or stylized wordmark anywhere on the page.
- [ ] No banned words, no superlatives without a linked source, no opinions in table cells, no em dashes.
- [ ] Switcher quote is verbatim, attributed, and permission is on file.
- [ ] `noindex` set; canonical is the page's own URL; a separate indexed version exists (or is planned) if the organic query matters.
- [ ] `gclid` and `utm_*` pass through to the CTA and reach the CRM.
- [ ] Rendered at 390 px and 1440 px; H1, sub-line and CTA visible without scrolling on the phone.
- [ ] Side by side with the site's homepage: header, type, colors and buttons match.
- [ ] Campaign spec delivered: exact/phrase keywords, negatives, ad copy without the mark, one ad group per intent, 60 to 90 day evaluation on cost per qualified opportunity.
- [ ] The risk owner approved the page before it went live.
- [ ] The risk owner approved the campaign (keywords, ad copy, budget, negatives) before it spends.

---

## 9. Sources

- Google Ads, Trademarks policy (keywords unrestricted; ad text restricted after a complaint; reseller and informational exemptions): https://support.google.com/adspolicy/answer/6118
- Google Ads, Destination requirements: https://support.google.com/adspolicy/answer/6368661
- Google Ads, Misrepresentation policy: https://support.google.com/adspolicy/answer/6020955
- Google Ads, About Quality Score: https://support.google.com/google-ads/answer/6167118
- Search Engine Land, Google's July 2023 trademark complaint change: https://searchengineland.com/google-ads-trademark-policy-change-advertisers-ads-428001
- FTC, Statement of Policy Regarding Comparative Advertising: https://www.ftc.gov/legal-library/browse/statement-policy-regarding-comparative-advertising
- FTC, Consumer Reviews and Testimonials Rule (in force October 21, 2024): https://www.ftc.gov/business-guidance/resources/consumer-reviews-testimonials-rule-questions-answers
- Ninth Circuit, Lerner & Rowe v. Brown, Engstrand & Shely (October 22, 2024): https://cdn.ca9.uscourts.gov/datastore/opinions/2024/10/22/23-16060.pdf
- EU Directive 2006/114/EC, Article 4: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32006L0114
- UK CAP Code, comparisons with identifiable competitors: https://www.asa.org.uk/advice-online/comparisons-identifiable-competitors.html
- ASA ruling, Practice Pal (February 25, 2026): https://www.asa.org.uk/rulings/practice-pal-a25-1281959-practice-pal.html
- HubSpot, navigation removal test (16 to 28% lift on mid-funnel pages): https://blog.hubspot.com/marketing/landing-page-navigation-ht
- HockeyStack Labs, transparent pricing and pipeline conversion: https://www.hockeystack.com/lab-blog-posts/state-of-pricing-demo-case-study-pages
- Grow and Convert, conversion rate by keyword type: https://www.growandconvert.com/conversion-rate-optimization/average-seo-conversion-rate/
- Conversion Factory, "acknowledge the dimensions where the competitor is better or even": https://conversionfactory.co/blog/competitor-comparison-page
- Google Ads Transparency Center: https://adstransparency.google.com
