DEV Community

Marco Kohns
Marco Kohns

Posted on

Building a price comparison site where every price comes from our own checkout runs

schliessfach24.de compares luggage lockers and luggage storage at German stations and airports. Its one rule: no advertised prices. Every number on the site comes from a checkout we ran up to the payment button, with a screenshot and a date. This post is about how that is built and kept honest.

Stack

  • Next.js with the App Router and Tailwind, statically generated pages per city and place (station, airport, trade fair, sight)
  • Supabase behind the scenes, content as typed data files per city in src/data/content/<city>/
  • Vercel, with main as production and a preview branch for every change

Research before code

Each city starts as a research document: every provider near a place, the checkout run for a fixed scenario (one regular suitcase, same-day drop-off and pick-up, plus an overnight case), the total including service and protection fees, the billing rule (per started 24 hours or per calendar day), opening hours, payment methods and the screenshot file names. Official sources come first: Deutsche Bahn station pages and the airport operator's price list.

The research is where the interesting findings come from. At Frankfurt Hbf, one suitcase overnight was 6.00 euros in a Deutsche Bahn locker and 11.99 or 13.65 euros through apps, because of fees and calendar-day billing. At Frankfurt Airport the apps' "airport" results were lockers 57 to 141 minutes' walk away.

A gate before every page

A content skill turns the research into the typed page data and then runs a blocking gate per city: every page needs at least one screenshot as evidence, at least two data visualisations, a FAQ with three or more questions, a visible "last checked" date and dateModified\ plus an author in the JSON-LD. It fails on noindex\, on banned words, on missing internal links inside the city cluster, and on any sentence that also appears on another city's page. Before a push, typecheck, build and an SEO audit against a local server have to pass too.

Structured data that matches the page

Each page emits one JSON-LD @graph: Organization and WebSite with stable @ids, the article with its image, a map (hasMap), and the provider list with prices and opening hours, so search engines read the same facts the visitor sees.

Keeping it fresh

Every page shows when it was last checked, and prices are re-run at least every 90 days. That cadence is the main cost of the product, and the reason it is worth trusting.

If you want to see the result, start with Frankfurt Hbf (the site is in German). Happy to answer questions about the pipeline in the comments.

Top comments (0)