CarExpert Choice Banners
2025Dynamic SVG badge system.

In 2025, CarExpert launched its first Choice awards recognising the best vehicles across 23 categories, with a winner and two finalists in each. For the editorial and product teams, that meant badges. Lots of them. A winner badge and a finalist badge for every category, appearing anywhere a nominated vehicle appeared across the site: article tiles on the news and reviews landing pages, showroom pages, buy pages, the compare tool.
Before a line of code was written, I watched the category naming process in practice. Our in-house designer was responsible for all the non-web assets printed materials, presentations, social graphics and the category names were still in flux. Names were being refined, split, reworded. Each change meant regenerating a set of files and redistributing them. I watched that happen enough times to know I didn't want the same process running on the website.
The scale of the problem
Think through what a static asset approach would have required. Three badge designs a dark banner, a light banner, and a compact block format each with a winner and finalist variant, for 23 categories. That's 138 unique files before a single name changes. When a category gets renamed and they were, repeatedly, right up to launch every affected file needs to be regenerated and redeployed. Do that three or four times across a busy pre-launch period and maintaining the badge assets becomes someone's full-time job.
The placement problem made it worse. Badges weren't confined to a dedicated awards page. They needed to surface anywhere a winner or finalist appeared which, on a site the size of CarExpert, meant hundreds of placements across multiple content types. Any static approach that worked for one context had to work for all of them.
The approach
My proposal was to skip static asset generation entirely and treat the badge as a dynamic component: three master SVG files (one per badge style), with the category name injected at render time.
The SVG holds everything the design, the branding, the visual variants for winner and finalist. The only thing it doesn't know at authoring time is the category name. At render, JavaScript finds the text node inside the SVG, replaces its content with the correct category, and toggles the winner or finalist visual variant. A rename in the CMS means updating one value. Nothing else changes.
I scoped this out with our internal developers before committing to make sure the approach was sound for the way the site was built. The in-house designer handled the badge designs; I handled the system that made them dynamic.
How it works
The key technical decision is how the SVG gets embedded. Loading SVGs via <img> is the default for most developers, but it doesn't allow JavaScript to access the SVG's internal DOM. Loading via <object> does and that DOM access is how everything else works.
Once the SVG is loaded, two operations run: a text replacement on the category <tspan> element, and a visibility toggle on two pre-designed <g> groups inside the SVG one for winner, one for finalist. The active group is set to display: block; the inactive one to display: none. The font Anek Latin is loaded inside the SVG's own <defs> block using a Google Fonts @import, which keeps the badge self-contained regardless of what the host page has loaded.
One edge case worth noting: the & character in category names like "Specialised & Off-road Vehicles" has to be escaped as & inside the SVG XML. The testing tool handles this transparently.
The handoff tool
The implementation was going to be handled by an offshore development team. That meant the system needed to be understandable without a walkthrough and testable without anyone having to guess whether a particular configuration looked right.
I built a standalone testing tool: a single HTML file that previews every combination of badge style, award status, and category name. A dropdown covers all 23 categories, toggles switch between winner and finalist and between the three badge styles, and the live preview updates immediately. The implementation documentation is embedded directly in the page as an accordion no separate doc to track down or fall out of sync.
One constraint the documentation flags: the tool must be served via a local web server, not opened as a file directly in a browser. CORS restrictions prevent JavaScript from accessing the SVG's internal DOM across the file:// protocol. The documentation provides the exact command to spin up a server, without it, the SVG DOM is silently inaccessible and the preview just doesn't update with no error to explain why.
Outcome
The category names kept changing after the system went live in testing. Nobody had to regenerate anything.
That was the goal. CarExpert's first Choice awards were being built while the awards themselves were still being defined categories were being named, renamed, and restructured in parallel with the site build. Designing for that reality wasn't over-engineering; it was the only sensible response to the actual conditions. The offshore team picked up the implementation from the tool and documentation without needing support. The awards launched on schedule.