Illustrative case study

A fictional business. The figures are a modelled scenario, not a client result.

Case study · Commerce SEO

Levometar

Personal-finance comparison site · Sofia, Bulgaria

How a Bulgarian comparison site turned live loan and deposit rates into thousands of ranking pages

+246%organic clicks to partners
in 11 months
FEEDS1234MONTH11of 11
Organic partner clicks+246%
1Partner clicks+246%scale 0–450%2Indexed pages3,900scale 0–4,0003Rich impressions+410%scale 0–450%4Affiliate revenue+138%scale 0–450%

01 · The jam

The coins were real. The machine never let Google see them.

Levometar's rate tables were loaded by script and updated manually, so Google saw empty pages and stale offers.

Levometar compares consumer loans, mortgages, deposits and cards from Bulgarian banks. Its editors knew the market, but the rates lived in a widget that filled itself in after the page loaded, from a spreadsheet someone updated when they had time. Search engines received headers and a spinner; visitors who did click through often met an offer the bank had already changed. Partners paid for clicks that never came.

Before · what Googlebot got

<table id="rates">
  <thead>…APR · Cost…</thead>
  <tbody>
    <!-- filled by rates.js -->
  </tbody>
</table>
<div class="spinner">
  Зареждане…
</div>

After · server-rendered

<table>
  <caption>Loans of 10,000 lv,
   60 months</caption>
  <tr><td>Bank A</td>
    <td>APR 8.9%</td>
    <td>checked 06:00</td></tr>
  …
</table>

02 · Assay report

Eight faults found in the mechanism.

A rendering, log-file and template audit across 4,300 candidate URLs and 18 live bank feeds, scored by how many coins each fault kept out of the tubes.

  1. T-01

    RenderingCritical

    Rate tables arrived by client-side XHR. The raw HTML of all 312 product templates held an empty <tbody>, so Googlebot indexed headers and a spinner.

  2. T-02

    FreshnessCritical

    Offers were re-keyed by hand from bank PDFs. Median offer age was 41 days; 23% of listed APRs no longer matched the bank’s own page.

  3. I-03

    IndexationHigh

    Only 180 of roughly 4,300 product, amount and term URLs were indexed. Filter parameters (?amount=, ?term=) canonicalised to the home page.

  4. S-04

    Structured dataHigh

    No FinancialProduct, LoanOrCredit or DepositAccount markup. Rates, fees and providers were invisible to rich results.

  5. C-05

    TemplatesMedium

    1,140 URLs shared the title “Кредити | Levometar”. Bank and product pages had no unique copy or representative examples.

  6. P-06

    PerformanceMedium

    A 610 KB rate-widget bundle pushed mobile LCP to 4.8 s and blocked the table from painting.

  7. L-07

    LinkingMedium

    Bank profile pages were orphaned. Nothing linked from a loan table to the provider or to neighbouring amounts and terms.

  8. A-08

    AttributionLow

    Partner links ran through a three-hop JavaScript redirect, so outbound clicks were under-counted and slow to land.

03 · Rebuilding the sorter

Four parts, one machine: feeds in, ranked offers out.

Built on our Commerce SEO plan: every offer enters once, from the bank’s own feed, and the same record drives the table, the markup and the page that ranks for it.

Part 01 · Hopper

Product feeds

Nightly XML and JSON feeds from 27 partner banks, hourly for deposits. Each offer is checked against the bank’s published rate before it can drop; a mismatch holds the coin in the hopper and flags it.

27 feeds · 6,800 offers checked daily

Part 02 · Rail

Comparison tables

Server-rendered HTML tables with a caption, a representative example, APR, total cost and a “checked” timestamp in every row. Sorting and filtering are progressive enhancement on top.

0 KB JS needed to read a rate

Part 03 · Assay stamp

FinancialProduct schema

LoanOrCredit and DepositAccount (both FinancialProduct types) with annualPercentageRate, interestRate, fees and provider on every offer, generated from the same feed record as the visible table.

100% schema/table parity

Part 04 · Sorting slots

Programmatic pages

Product × amount × term templates, published only when a combination has at least three live offers and enough unique copy. Thin combinations stay noindex until they fill.

3,900 pages passed the gate

04 · 11 turns of the crank

Month by month, the indexed-pages tube filled.

  1. MONTH 01180 pages

    Assay

    Render and log-file audit; feed contracts agreed with partner banks.

  2. MONTH 02420 pages

    Feed intake

    First 9 bank feeds wired in; validation rules against published rates.

  3. MONTH 03960 pages

    Server tables

    Loan and deposit tables rendered on the server; widget bundle retired.

  4. MONTH 041,640 pages

    Schema stamp

    LoanOrCredit and DepositAccount markup shipped from the feed record.

  5. MONTH 052,210 pages

    Slots, wave 1

    Amount × term templates for consumer and mortgage loans behind the quality gate.

  6. MONTH 062,700 pages

    Bank pages

    Provider profiles rebuilt and linked from every table row.

  7. MONTH 073,080 pages

    Deposits

    Hourly deposit feeds; term-deposit pages by duration and currency.

  8. MONTH 083,390 pages

    Slots, wave 2

    Credit cards and refinancing; city pages only where branches exist.

  9. MONTH 093,610 pages

    Titles

    Template titles carry the best live APR and the check date.

  10. MONTH 103,780 pages

    Redirects

    Partner links reduced to a single tracked hop; click parity restored.

  11. MONTH 113,900 pages

    Calibration

    Pruned 210 thin combinations; feeds 18 to 27; handover runbook.

05 · The tubes, counted

+246% organic clicks to partners, and every tube fuller.

Modelled scenario for a fictional business — not a client result. Rankings and traffic are never guaranteed; see our Terms.

Organic partner clicks

+246%

Base +0%M11 +246%

One coin ≈ +19%

Indexed offer pages

180 → 3,900

Base 180M11 3,900

One coin ≈ 167 pages; grey = before

Rich result impressions

+410%

Base +0%M11 +410%

One coin ≈ +19%

Affiliate revenue

+138%

Base +0%M11 +138%

One coin ≈ +19%

Keyword ledger

Google.bg positions, month 0 vs month 11. Modelled monthly searches.

QuerySearchesBeforeAfter
потребителски кредитconsumer loan18,100343
кредит 10000 лв10,000 lev loan4,400—1
депозити лихвиdeposit rates9,900414
ипотечен кредит сравнениеmortgage comparison2,900222
кредит за рефинансиранеrefinancing loan3,600—5
срочен депозит 12 месеца12-month term deposit1,900—2
кредитна карта без таксаno-fee credit card2,400586
бърз кредит онлайнquick online loan12,100639

“—” means not in the top 100.

The same query, before and after

Month 0 · position 34

levometar.bg › krediti

Кредити | Levometar

Зареждане… Сравнете оферти. APR · Cost · Bank …

Month 11 · position 3 · rich result

levometar.bg › krediti › 10000-leva

Кредит 10 000 лв за 60 месеца — от 8,9% ГПР

Bank A8,9%12 418 лв
Bank B9,4%12 571 лв
Bank C9,8%12 690 лв

Checked today 06:00 · 14 offers

Get a plan like this

If your catalogue, rates or listings change faster than Google can see them, Commerce SEO turns the feed you already have into pages that rank.