Outcropby Basalt

Guide ·

Comparison and pricing pages for a software product: what to put on them

Three pages do most of the work when someone is about to choose a tool: an alternatives page, a “you vs them” page and a pricing page. Here is what each should hold, a terminal command that checks each part, and what is on our own comparison pages, with dates.

Why these pages

The people searching them are close to choosing

Someone who searches “[competitor] alternative” already wants a tool like yours. Someone who searches “[you] vs [them]” has narrowed it to two. Fewer people search these than broad topics, and the ones who do are close to picking. The pricing page is often the last page they read before they pay.

Most small software sites do not have these pages ready. In our study of 1,000 Show HN launch sites, checked without JavaScript on 20 Oct 2026, 148 of the 928 sites we reached (15.9%) had any comparison, vs or alternatives page, and 197 (21.2%) had a pricing page a crawler could find. Of the roughly 264 sites that showed a sign of selling something, 103 had a comparison page. The study counted with text rules checked by hand; its limits are on its page.

Before you start

Set your address once

The checks use curl, grep, sed and perl, which come with macOS and most Linux systems, and work the same in zsh and bash. Set your site’s address once, without a slash at the end. Steps that check one page set that page’s address too.

site=https://example.com

Page 1 · Alternatives

An alternatives page: a list where you are one option

Searched as “[competitor] alternative” or “[competitor] alternatives for Mac”. The reader is leaving a tool, or never liked it, and wants the field in one place.

  1. Write one alternatives page, with you as one option

    Do

    Name the tools your buyers already weigh, yours included, in one table near the top: price, platforms, licence and the one or two features buyers ask about. Then a short section on each tool. Write it for a reader who has not picked yet, and put the date you checked the prices on the page.

    Check

    This prints the comparison and alternatives pages listed in your sitemap. No output means a buyer searching “[competitor] alternative” has no page of yours to land on.

    curl -s "$site/sitemap.xml" | grep -o '<loc>[^<]*' | sed 's/<loc>//' | grep -i -E 'alternative|(^|[/-])vs([/-]|$)|versus|compar'
    On our sites

    Upright, Basalt’s free Mac app for Logitech mice, got a Logi Options+ alternatives page on 18 Oct 2026 (proof page). It compares 8 apps in one table, Logi Options+ included, and is dated “Updated October 20, 2026”. Run on Upright, the command printed:

    https://upright.hellobasalt.dev/logi-options-alternatives
    https://upright.hellobasalt.dev/upright-vs-mac-mouse-fix
    https://upright.hellobasalt.dev/upright-vs-bettermouse
    https://upright.hellobasalt.dev/upright-vs-steermouse
    https://upright.hellobasalt.dev/upright-vs-openlogi

    The last line is a fourth vs page, dated 20 Oct on the page itself.

  2. Say who each tool suits, yours included

    Do

    End with a “which one should you pick?” list: one line per kind of buyer, and the tool that fits them. Some lines should point away from you. That is what makes the page a comparison and not an ad.

    Check

    This prints the page’s section headings. You want one per tool and one that helps the reader choose.

    page="$site/your-alternatives-page"
    curl -s "$page" | grep -o -E '<h[23][^>]*>[^<]+' | sed -E 's/<h[23][^>]*>//'
    On our sites

    On Upright’s alternatives page it printed one heading per app and a section for choosing. Five of that section’s six lines send the reader to another app: OpenLogi, Mouser, BetterMouse, Mac Mouse Fix or LinearMouse, and SteerMouse.

    At a glance
    Upright
    OpenLogi
    Mouser
    BetterMouse
    Mac Mouse Fix
    SteerMouse
    LinearMouse
    Which one should you pick?
    FAQ

Page 2 · You vs them

A “you vs them” page: a dated table, and where they win

Searched as “[you] vs [them]” or “[them] vs [you]”. The reader has narrowed it to two, so write one page for each rival buyers name.

  1. Put a dated table at the top

    Do

    One table near the top, with the same rows for both products. Put the date you checked their facts next to it, and link the pages you took them from. Their prices and features change; the date tells the reader how old your facts are, and tells you when to check again.

    Check

    The first command counts the tables in the page’s HTML. The second prints any “checked”, “updated” or “written” date in its text.

    page="$site/you-vs-them"
    curl -s "$page" | grep -c '<table'
    curl -s "$page" | perl -0777 -pe 's/<[^>]+>/ /g' | grep -o -i -E '(checked|updated|written) [^.]{0,30}20[0-9]{2}' | sort -u -f
    On our sites

    Upright’s three “vs” pages went live on 19 Oct 2026 (proof page): vs Mac Mouse Fix, vs BetterMouse and vs SteerMouse. Each has one “At a glance” table, the line “Checked 19 October 2026 · Facts from each developer’s own site” under the title, and its sources at the end. On vs Mac Mouse Fix the commands printed:

    1
    Checked 19 October 2026

    KahveDrop, our Turkish coffee finder, linked and dated its comparison page on 20 Oct: it answers ten “which one?” questions with 250 g prices side by side, under the line “Son güncelleme: 20 Ekim 2026” (last updated).

  2. Say where they win

    Do

    Add a short “which should you pick?” list and give them the lines they win: more devices, a lower price, a longer track record. Say what yours does not do yet, too.

    Check

    Put their product’s name in them. This prints every line where your page tells the reader to choose them. No output means the page never does.

    page="$site/you-vs-them"; them="Their App"
    curl -s "$page" | perl -0777 -pe 's/<[^>]+>//g' | grep -i -E "(choose |pick |: )$them" | sed 's/^ *//'
    On our sites

    Each of Upright’s three vs pages gives the other app half or more of its “Which should you pick?” lines: 3 of 6 on vs Mac Mouse Fix, 3 of 6 on vs BetterMouse and 3 of 5 on vs SteerMouse. On vs BetterMouse the command printed:

    You want the most Logitech hardware control without Logi Options+: BetterMouse. Onboard profiles, the MX Master thumb wheel and keyboard settings are things Upright doesn't do.
    You also have a Logitech keyboard, or need to pair a Unifying or Bolt receiver: BetterMouse.
    You want a notarized app with polished smooth scrolling, and $7.99 is fine: BetterMouse.

    Upright’s MX Master 3S on Mac without Logi Options+ page, live on 20 Oct, says near the top: “Read this first: it is not tested on this mouse.”

  3. Put both prices in the HTML

    Do

    Write their price and yours as text in the table, with the date you checked, not in an image or a widget. The reader came to compare cost, and a crawler that does not run JavaScript sees only what is in the HTML.

    Check

    This prints each price in the page’s text without scripts and styles, and how often it appears. Their price should be there, and so should yours unless the product is free. It looks for $, € and £; change the pattern for other currencies.

    curl -s "$page" | perl -0777 -pe 's/<(script|style)\b.*?<\/\1>//gis; s/<[^>]+>/ /g' | grep -o -E '(US)?[$€£] ?[0-9][0-9,]*(\.[0-9]{2})?' | sort | uniq -c
    On our sites

    Upright is free, so its column says “Free”. The other app’s price is in the HTML of each page: $2.99 on vs Mac Mouse Fix, $7.99 on vs BetterMouse, and on vs SteerMouse the command printed:

       3 US$12.99
       4 US$19.99

Page 3 · Pricing

A pricing page a crawler can read

In our study, 38 of 197 pricing pages showed no price in the HTML without JavaScript, 29 of the 179 we could match against a sitemap were missing from it, 3 were marked noindex, and 61 of 197 described the price in structured data.

  1. Put the price in the HTML, not only in JavaScript

    Do

    Plan names, prices, currency and billing period should be in the HTML the server sends. A pricing table drawn by a script reaches a crawler that does not run JavaScript empty.

    Check

    Set your pricing page’s address. The first command counts the words without JavaScript, the second prints the prices among them. A few dozen words and no prices means the page is drawn by JavaScript.

    pricing="$site/pricing"
    curl -s "$pricing" | perl -0777 -pe 's/<(script|style)\b.*?<\/\1>//gis; s/<[^>]+>/ /g' | wc -w
    curl -s "$pricing" | perl -0777 -pe 's/<(script|style)\b.*?<\/\1>//gis; s/<[^>]+>/ /g' | grep -o -E '(US)?[$€£] ?[0-9][0-9,]*(\.[0-9]{2})?' | sort | uniq -c
    On our sites

    Outcrop has no /pricing page: /services/ lists every package with its price, and each package page shows its own. With pricing="$site/services/", the commands printed:

         407
       2 $1,490
       1 $290
       1 $490
       2 $690
       1 $790
       1 $890
       1 $990
  2. List it in the sitemap, and do not noindex it

    Do

    Put the pricing page in your sitemap, at the same address as its canonical tag. Check that no meta robots tag or X-Robots-Tag header marks it noindex.

    Check

    The first command should print 1; use the address exactly as your sitemap writes it, trailing slash included. The other two should print nothing.

    curl -s "$site/sitemap.xml" | grep -c "<loc>$pricing</loc>"
    curl -s "$pricing" | grep -i -o '<meta[^>]*robots[^>]*>'
    curl -s -I "$pricing" | grep -i '^x-robots-tag'
    On our sites

    Run on Outcrop’s /services/, the first command printed 1 and the other two printed nothing.

  3. Describe the price in structured data

    Do

    Add an Offer with a price and a priceCurrency for each plan to the page’s JSON-LD, attached to the product it sells. Keep the prices the same as the visible ones.

    Check

    The first command counts the Offer and Product blocks, the second prints the prices and currencies in them. Compare them with the prices on the page. Google’s Rich Results Test shows the same, with errors explained.

    curl -s "$pricing" | grep -o -E '"@type": ?"(Offer|AggregateOffer|Product|OfferCatalog)"' | sort | uniq -c
    curl -s "$pricing" | grep -o -E '"(price|priceCurrency)": ?"?[^,}"]+"?' | sort | uniq -c
    On our sites

    Outcrop’s build writes the visible prices and the Offers from the same list of packages. Run on /services/, the commands printed:

       6 "@type":"Offer"
       1 "@type":"OfferCatalog"
       1 "price":1490
       1 "price":290
       1 "price":490
       1 "price":690
       1 "price":790
       1 "price":990
       6 "priceCurrency":"USD"

Results

What we cannot tell you yet

Whether these pages bring buyers. Upright’s comparison pages are days old, and Search Console has no impressions for them yet. Their numbers go on the proof page at 2, 4 and 8 weeks after each change, bad weeks included.