BMW Club Moldova
24 years of club history · trilingual · live

BMW Club Moldova

Next.jsTypeScriptTailwindnext-intlFlickr API

The starting point

BMW Club Moldova has been the country's official BMW owners' club since 2002 — part of the pan-European BMW Clubs Europe network, with 40+ active members and two decades of rallies, festivals, and meetups behind it. The club's site had outgrown its old WordPress setup: an archive of nearly 90 blog posts, a membership process run by hand over email, and no real path to the trilingual audience the club actually has — Romanian, Russian, and increasingly English.

The approach

Rebuilt on Next.js with Romanian as the default locale (no URL prefix, since that's the primary audience) and Russian/English alongside it. A few decisions did most of the work:

Migrated ~90 WordPress posts without breaking their links. Old post URLs redirect to their re-platformed equivalents instead of 404ing — two decades of accumulated backlinks and search rankings don't get thrown away just because the CMS changed underneath them.

Membership applications go straight to Telegram, not an inbox. Applicants fill in a form on the site; the board gets a message with Accept/Decline buttons and can act on it from their phone. No inbox to check, no manual data entry, no applications quietly going stale.

A BMW encyclopedia backed by a small AI research pipeline. Rather than hand-writing chassis history for every generation, a companion CLI researches a chassis (Anthropic API + web search), drafts entries in all three languages, and leaves them as a reviewable diff — nothing publishes without a human reading the sources first. Five entries (E92, F30, E34, E53, E87) shipped this way.

A photo gallery spanning the club's full history, pulled live from Flickr — 39 albums, 2002 to today — instead of re-hosting and maintaining thousands of images.

Technical stack

Next.js 16 (Turbopack), TypeScript, Tailwind CSS v4, next-intl, Vitest. No database — content lives in MDX and typed data files, and the two pieces of real "state" (photos, membership approvals) live where they already belong: Flickr and Telegram. Keeps hosting and ongoing maintenance close to zero.

Result

This one isn't a three-week sprint like the builds above — it's a site I actively maintain for a community I'm part of. Recent work: closed a metadata bug where every page's Open Graph tags were silently dropping their image and site name (a genuine Next.js gotcha — a page that sets its own openGraph replaces the parent's wholesale instead of merging it), fixed a gallery filter that was hard-capped to 6 albums out of 39, shipped a full-bleed photo hero, and moved the site onto its own domain with analytics and search console verification wired up.

Why it matters

Trilingual from the architecture up means the club's Russian- and English-speaking members were never a future migration — they were served from day one.

Telegram-based approvals got adopted because the friction was removed, not because anyone was told to use a new tool. A feature nobody has to remember to check wins by default.

The AI research pipeline stays reviewable on purpose. Getting a chassis's known weak points or engine specs wrong would cost real trust with an enthusiast audience — so speed only counts here if accuracy isn't the price.

The Open Graph bug is the more universal lesson. It's the kind of quiet SEO leak — pages silently missing their preview image and title on every share — that costs real visibility for months before anyone thinks to check. Worth auditing even on a site everyone assumes "already works."

This is volunteer work for a community I'm part of, not a paid engagement — so there's no client invoice to point to. But the standard is the same one I'd hold a client project to, and it's the same audit I'd run on any existing site before touching a line of new feature code.


Migrating an old WordPress site, or wondering what's quietly broken in your own site's metadata? Let's talk.