A bilingual website for a Lviv law firm, on a CMS the team runs themselves — and the AWS deployment, backups and release pipeline behind it.
The firm needed a website that builds confidence in the first seconds, presents a broad practice clearly, and lets the team publish updates without calling a developer.
It also had to work in two languages. Lviv firms serve Ukrainian clients and foreign ones, and a second language bolted on later is a second site to maintain — so Ukrainian and English had to be one site from the start.
Payload CMS runs inside the same Next.js application, so the site and its admin are one deployment rather than two services to keep in sync. Every page, practice area, lawyer and article is a CMS document, and every translatable field is translated in the CMS instead of in the code.
Visitors never wait for that content. Each page ships as a full static shell, and the cached reads are tagged with the exact documents they touched — when an editor saves, Payload hooks invalidate those tags and nothing else. The result is a site that reads like a static one and updates like a dynamic one.
Ukrainian and English throughout — pages, practice areas, lawyers, articles and metadata. Ukrainian is unprefixed, English lives under /en.
Corporate, civil, commercial, employment, family and intellectual-property law, each with its own page and its own route to a consultation.
A page per lawyer, an article journal and an FAQ — added and edited by the firm, with no developer in the loop.
Stored in the CMS and emailed to the firm, behind a honeypot, a minimum fill time and rate limiting — so nothing is lost and little of it is spam.
Sitemap, llms.txt and a Markdown mirror of every page, plus generated social images — the firm shows up correctly in search and in AI answers.
Checks, database backup, migrations, image build, audit, ship over SSH, smoke test — and an automatic rollback if the new version does not answer.
The site runs as a single Docker container on AWS Lightsail, described in Terraform, with the database on Turso and media on S3 behind CloudFront. It is the firm’s own infrastructure and their own domain — not a deployment living in my account.
A release is one command, and it refuses to ship a broken build: the pipeline audits the image before it goes out — static rendering, SEO, image weight, Lighthouse — and rolls back on its own if the smoke test fails. Backups run before every migration.
Practice areas are the first thing a visitor sees, each explained in plain language with a single obvious next step. Both language versions stay complete because they are the same documents, not two copies.
The firm publishes its own articles, edits its own team page and reads its own inquiries. Nothing on the site needs a developer to change — which is the part that made it worth building this way.
Tell me what your business does and what you need. I'll come back with a scope, a timeline and a price.
Start a project