Skip to main content

Dr. Tire

Local BusinessAutomotiveActive

A small bilingual site for a mobile tyre service that comes to the customer in Kyiv, replacing a legacy WordPress install. Built to be cheap to run and to need no attention: no database, no CMS, no admin panel.

Client
Doktor Pokryshkin, a mobile tyre service in Kyiv
My role
Design and development, end to end
Period
2026
Dr. Tire

Project Overview

A friend runs a mobile tyre service out of a van: no garage, no forecourt, he drives to wherever the flat happened. The old site was a WordPress that had aged into a liability - plugins to update, a database to keep alive, an admin panel nobody logged into. The replacement keeps the useful part and throws away the rest. The content is in the repository, the prices are one JSON file, and the whole site builds to static pages, so running it costs a container and an hour of attention when something changes. The interesting constraint was restraint: for a business with six pages, the right amount of framework is almost none, and every dependency not added is one that never needs a security update.

The project in numbers

Stack

Legacy WordPress

toNext.js, no database

Content lives in the repository - copy in two locale files, prices in one JSON - so there is nothing to back up, nothing to patch on a Tuesday, and no admin login for anyone to lose.

Runtime dependencies

Four

next, next-intl, react and react-dom. No UI kit, no CSS framework, no component library: on a site this size each one would cost more in weight and upgrades than it saves in typing.

Rendering

Every page static, enforced at build

The route table has to come out fully prerendered; a dynamic page appearing in it is treated as a defect, because it means something leaked in through search params or a forgotten locale call.

Client-side JavaScript

Five islands, and that is all

Language switcher, active nav item, the live tyre-size field, the lead form and conversion tracking. Everything else is markup - an accordion is a details element, a choice is radio buttons, a form is a server action.

Enquiries

Straight to Telegram

A server action posts each form to the owner's chat, several recipients at once if needed. A tyre fitter who works from a van reads Telegram; he does not log into a dashboard.

Challenges

  • Replacing a WordPress on a budget where a monthly maintenance bill is not an option.
  • Serving Ukrainian and Russian equally, because the customer base reads both, without doubling the work of every edit.
  • Making enquiries reach a man who is under a car, not at a desk.
  • Being found: a mobile service has no address to put on a map, which is the one thing local search normally keys on.
  • Keeping the whole thing maintainable by someone who is not a developer and edits prices a few times a year.

Solutions

  • Rebuilt the site on Next.js 16 with the App Router and next-intl, Ukrainian as the unprefixed default and Russian under /ru, with the two locale files structurally identical so a missing key fails type-checking rather than production.
  • Dropped the database entirely: copy lives in the locale files, prices in a single JSON keyed by service id, and components hold no prices or prose of their own.
  • Kept every page static, and made that a build rule rather than a hope - a route that turns dynamic is a defect to investigate, not a fact to accept.
  • Held the client-side JavaScript to five islands and solved the rest with markup, because an accordion is a details element and a form is a server action.
  • Routed enquiry forms to Telegram through a server action, to one chat or several, since that is where the owner already is.
  • Marked the business up as an AutoRepair local business with areaServed describing the coverage rather than an address, because the whole point is that there is no salon to visit - plus per-page canonicals, hreflang and a sitemap.
  • Wired Google Ads conversion tracking to the actions that matter for this business - taps on the phone number, Viber and Telegram - without letting the ad script delay the call.
  • Shipped it as a plain Docker Compose stack with a push-to-deploy pipeline through GitHub Actions and Docker Hub, reporting to Telegram when it lands.

Key Features

  • Bilingual - Ukrainian and Russian, with structurally identical locale files enforced by the type checker.
  • Prices in One File - Service prices in a single JSON, keyed by id, editable without touching a component.
  • Live Tyre Size Field - The one piece of real interactivity on the site, for people who know their size and people who do not.
  • Telegram Enquiries - Callback, order and tyre-request forms delivered by a server action to the owner's chat.
  • Local SEO Without an Address - AutoRepair markup with areaServed, canonicals, hreflang and a sitemap.
  • Ad Conversion Tracking - Phone, Viber and Telegram taps reported to Google Ads without delaying the action.
  • Static by Rule - Every page prerendered, checked on every build.
  • Push to Deploy - GitHub Actions to Docker Hub to the server, with a Telegram notification.

Project Info

Launch Date:
September 9, 2026
Status:
Active

Technologies

Frontend

Next.js 16 (App Router)ReactTypeScriptnext-intlServer ActionsPlain CSS

Translations

next-intl (UK/RU)Type-checked locale parity

Messaging

Telegram Bot API

Security

No database, no admin panel, no stored customer data

Hosting & Deployment

DockerDocker ComposeDocker Hub

DevOps & CI/CD

GitHub ActionsPush-to-deploy with Telegram notification

Monitoring & Analytics

Google Ads conversion tracking
Available for new projects

Need something like this?

Tell me what you are building and where it is stuck. I will tell you plainly whether it is work I should be doing.