Building Bazarnicek: One Search Across Every Czech Second-Hand Market
Bazarnicek is a friendly meta-search for the Czech second-hand market: one search across 20+ classifieds — Bazoš, Sbazar, Aukro, Vinted, Facebook Marketplace and more — with price intelligence and watchdog alerts, sending motivated buyers straight to the original listings. Here is what it is, what it does, and the engineering challenges behind making 20+ marketplaces feel like one calm product.

Fun Fact
A single Bazarnicek results page runs a live search across 20+ marketplaces at once and links every result straight back to its source — an aggregator that sends buyers onward, not one that keeps them.
Most of my writing here is about other people's engineering organizations. Bazarnicek is the opposite: it is the product I built for myself, then for everyone else. The Czech second-hand market is huge but hopelessly fragmented — Bazoš, Sbazar, Aukro, Vinted, Facebook Marketplace, Mimibazar and a dozen more, each with its own search, its own account, its own quirks. In 2024, while hunting for baby gear across all of them for the tenth time, I decided there had to be a better way. Bazarnicek is that better way: a price-comparison layer for the whole market that finds the item wherever it is and points you to the original listing. This is what it does — and the genuinely hard problems behind making it work.
What Bazarnicek Actually Is
Bazarnicek is a meta-search for the Czech second-hand market. You type what you want once, and it searches 20+ marketplaces in parallel, then merges, de-duplicates and ranks the results into a single feed — with every result linking straight back to the original listing on the source site.
One search, whole market: instead of opening ten tabs, you get one. Coverage spans the portals that make up the vast majority of Czech second-hand supply.
Watchdogs: set an alert for a specific product and get an email the moment a new matching listing appears anywhere — the feature people actually stay for.
Price intelligence: each product page shows what the item usually goes for (range, typical price, a small histogram) so you can tell a deal from a rip-off at a glance.
The product's job is to make a fragmented market feel like one place — and to be a good neighbor to the sources it links to, sending them ready-to-buy visitors rather than competing with them.
Challenge 1: Making 20+ Different Marketplaces Feel Like One
Aggregation sounds simple until you meet the reality: every marketplace has its own page structure, its own search parameters, its own categories and its own data shape. Integrating them is like writing 20+ small, independent adapters that all have to produce one clean, normalized listing the rest of the app can trust.
A friendly neighbor, not a competitor: Bazarnicek works as a meta-search and price-comparison layer. Every result links straight back to the original listing on the source site, so the marketplaces get qualified, ready-to-buy traffic. The whole design goal is to add value on top of the ecosystem and send people onward — the same white-hat posture a price comparison or a search engine takes.
Resilience is the real work: sites change their markup, so an adapter that worked yesterday can quietly break. A big reliability win was making every integration failure loud and logged, so a broken source shows up in monitoring instead of silently degrading results — a visible outage beats invisible rot every time.
Challenge 2: Being a Good Citizen With Live Data
A Bazarnicek results page is not reading a stale database — it runs a live search across the sources at request time, so what you see is genuinely current. Live data, though, has to be handled responsibly, and being a considerate guest is a first-class design constraint here, not an afterthought.
Cache to lighten the load: results are cached with a stale-while-revalidate strategy so repeat visitors and crawlers do not each re-trigger work against the sources. Request volume stays modest and well-behaved; the sources are treated as partners, not targets.
Always send people onward: the product never tries to be the destination. It finds the item, gives it price context, and hands the visitor to the original listing. Fresh and useful, without being a burden on anyone it depends on — that is the balance the engineering is tuned around.
Challenge 3: Teaching Google That One Query Is One Page
Bazarnicek's growth engine is organic search: a landing page per product query. But the same intent can be typed a dozen ways — with and without Czech diacritics, spaces vs. hyphens, different word order, URL-encoded variants. Left alone, that splinters ranking signals across near-duplicate URLs.
Canonicalization pipeline: every query is normalized to one canonical, ASCII, hyphenated slug, and everything else 301-redirects to it. The rule set is guarded by an offline test that runs the entire corpus of ~9,000 real queries on every change, with zero HTTP requests — so I can refactor the normalizer fearlessly and know instantly if a single query would resolve differently.
Lossy slugs, honest titles: the slug is deliberately lossy (no diacritics, no casing), which means it cannot be turned back into a proper title. So the display name — the H1, the page title, the query actually sent to the marketplaces — comes from a separate map built over what real people typed. Four different strings for one term, each with a job, and an invariant that keeps them from ever describing different things.
Challenge 4: Programmatic SEO Without the Thin-Content Trap
Thousands of auto-generated landing pages is exactly the pattern Google penalizes as scaled, thin content — unless each page genuinely earns its place. That was the line I refused to cross.
Every page has to be worth indexing: a landing page is not just a list of listings. It carries a hand-checked buying guide (what to watch out for when buying this thing second-hand), real price statistics with a histogram, related-search crosslinks, breadcrumbs and a category. If a term cannot support real content and real listings, it does not go in the sitemap.
Demand as the quality gate: the sitemap is generated from actual search demand and evidence of live listings, not from a keyword dump. Low-volume long-tail terms are often the purest demand signal — a real human typed them — whereas some high-volume terms are inflated by their own Google clicks. The goal is a few thousand strong pages that let the crawler discover the long tail, not tens of thousands of empty buckets.
Challenge 5: Location That Actually Filters
People want results near them, so the filter maps a municipality to a postcode (a municipality name is friendlier and better for SEO; the postcode is unambiguous — there are dozens of villages called Lhota). Simple in principle. In practice, every marketplace models location differently.
One model at a time: some take a postcode plus a radius, some a district ID, some a city name, some none at all. Working through each marketplace's own location model — and matching it to a clean municipality-to-postcode mapping on our side — was a big chunk of the work.
A source-agnostic backstop: because not every source exposes a reliable location filter, there is a safety net on our side. Results are softly re-ranked so genuinely local listings float to the top, and any listing that clearly sits in a different region gets a subtle badge — nothing is hidden, but the user is told at a glance which results might be somewhere else. The correctness lives with us, not with the least-reliable source.
The Stack
The app is Next.js on the App Router, deployed on Vercel, with results pages rendered dynamically because they are inherently live. Listing parsing is done with Cheerio. Persistence — users, watchdogs, query stats, price history — runs on Appwrite. Product analytics go to PostHog and error/performance monitoring to Sentry.
None of these choices are exotic. The interesting part is not the stack; it is the accumulated set of small, hard-won decisions about how to make an aggregator resilient, considerate and genuinely useful when it sits on top of two dozen sources it does not own.
If you have read The Turnaround Playbook, you will recognize the instinct here too: diagnose the real constraint before optimizing anything. For Bazarnicek the real constraint was never raw speed — it was being a good citizen to the sources, and never shipping a page that did not deserve to exist.
Conclusion
Bazarnicek looks like a simple search box, and that is the whole point — the complexity is supposed to be invisible. Behind it sits a live meta-search across 20+ diverse marketplaces, a canonicalization layer that keeps a few thousand landing pages honest, a careful per-marketplace integration effort, and a good-citizen discipline: cache to lighten the load, respect the sources, and always send buyers onward to the original listing. Building it solo forced the same lesson I bring to every engineering org I advise: the hardest problems are rarely the ones that look hardest. The integration was fiddly, but the real work was in the constraints — being considerate to sources, content quality, correctness — that decide whether an aggregator is a toy or a product people trust. You can try it at bazarnicek.cz.
Key Takeaways
- A good aggregator is a good neighbor: send qualified traffic back to your sources and link out, do not compete with them
- Normalizing 20+ different data shapes into one clean, trustworthy model is the real work of aggregation
- Make every integration failure loud and logged — silent degradation is worse than a visible outage
- Programmatic SEO only works if every generated page genuinely earns its index slot; gate on real demand
- One search intent must map to exactly one canonical URL, guarded by fast offline tests
- When you integrate systems you do not own, put the correctness backstop on your own side
- Cache with stale-while-revalidate so live data stays fresh without burdening your sources

About the Author
Vojtech Gintner - CTO @ Finviz
"Turning Engineering Chaos into Business Value"
Real-world leadership, not just theory. As the active CTO of Finviz, I don't just advise on strategy—I execute it daily. I navigate the same market shifts, technical bottlenecks, and leadership challenges that you do.
With 20 years of hands-on engineering experience (from React/Node to distributed infrastructure), I specialize in turning chaotic software organizations into scalable, high-performing assets. I bridge the gap between business goals and technical reality—speaking the language of your board and your developers.
I also founded Busfactor, the engineering intelligence platform that reads your repos and shows where knowledge risk, delivery queues and engineering cost sit.
Continue Reading

Engineering Leadership Through Extreme Change
How I led 75% of Deepnote's engineering organization through restructuring, layoffs, and rapid expansion while maintaining velocity and rebuilding trust.

Busfactor: The Audit I Run as a Fractional CTO, Now Self-Serve
I run about 50 direct reports as CTO with no middle layer, and things slipped. The tools that could have caught it cost too much, so I built the read myself. Why I built Busfactor, what it shows, and how I use it in fractional CTO audits.
Interested in similar results for your organization?
Let's discuss how I can help your engineering team overcome challenges and achieve ambitious goals.
Get in Touch