Skip to content
Case Study3 weeks7 min read

Dental clinic migration from Laravel to Next.js + .NET 9 — 6 languages, 1,333 URLs, zero SEO drop

The Clinic Praha is a reputable dental clinic with an international client base. Their legacy Laravel site offered only 2 languages, had broken meta descriptions and minimal structured data. We delivered a full rewrite: a Next.js 16 public website, a React admin portal and a .NET 9 backend — all in a single Docker image on Azure. In 3 weeks and 116 commits.

6 languagesincluding RTL ArabicCS · EN · DE · FR · RU · AR
1,333URLs in sitemap3× more than the old site (539)
97.6%redirect coverageno loss of SEO rankings
3 weeksfrom first commit to handover116 commits
01 — Starting point

The legacy Laravel site was blocking expansion to foreign patients

The Clinic Praha serves patients from Germany, France, Russia and the Arab world, but the old site only spoke Czech and English. On top of that, technical SEO problems were holding back organic growth — missing structured data, broken canonical URLs and fallback meta descriptions reading "Page not found" on treatment detail pages. The migration could not damage existing Google rankings or backlinks.

Site languagesonly 2 (CS, EN)
Meta descriptionsfallback "Page not found"
Canonical URLcontained /public/ prefix
Structured dataonly homepage JSON-LD
Hreflang coverageincomplete, CS + EN only
Content updatesrequired a developer
Starting point
539 indexed URLsin 2 languages, no rich snippets, no self-service CMS
02 — Solution

Monorepo in a single Docker image: Next.js 16 + .NET 9 + React admin

We built the entire system from scratch. One .NET 9 process hosts the backend API, serves the static admin SPA and, via a YARP proxy, routes the root to Next.js SSR. Fewer containers, simpler ops, one CI/CD pipeline.

01

.NET 9 + EF Core + PostgreSQL backend

ASP.NET Core 9 REST API on Azure-managed PostgreSQL. The host app also serves the static admin and uses a YARP proxy to forward requests to the Next.js SSR process. Everything in a single Docker image from Azure Container Registry.

02

Public website — Next.js 16 + React 19 + Tailwind 4

Full SSR across all 6 languages (25 page types × 6 locales). Per-locale slugs, dynamically generated OG images on the Edge runtime and in-memory redirect cache for zero DB load on every request.

03

AI-assisted translation pipeline

Every entity has source Czech content and N translation records. A Czech edit triggers a TranslationBackgroundJob that issues a batch request to the Anthropic Claude API, polls asynchronously and applies the results to the database. A translation audit dashboard shows editors what is still missing.

04

AI sitemap matcher + redirect system

An LLM compared 536 URLs from the old site with 1,333 on the new one and proposed redirects for 97.6% of cases. A redirect database with 12-month retention, chain flattening (no A→B→C hops) and automatic redirects when an editor changes a slug. Middleware caches 308 redirects with a 3-minute TTL.

05

E-commerce-grade SEO

17 JSON-LD types: MedicalOrganization, Physician, MedicalProcedure, FAQPage, JobPosting, BreadcrumbList and more. AggregateRating from imported Google reviews drives star ratings in SERPs. Full hreflang for 6 languages plus x-default on every URL.

06

Admin portal with 14 CRUD sections

React 19 + Vite 8 + Material-UI 7. Doctors, treatments, branches, pricing, Q&A, academy, news, books, careers, reviews (auto-imported from Google), translations, redirects, CDN files, users. Google OAuth 2.0 with email allowlist plus audit trail with point-in-time recovery.

07

Analytics for PPC performance campaigns

Google Tag Manager with Consent Mode v2 (GDPR). Conversion events newsletter_signup, phone_click, email_click and booking_click carry CZK values for Google Ads Smart Bidding. Cookie banner and legal pages in 6 languages.

03 — Architecture

Solution Architecture

The whole system runs as one Docker container — a .NET 9 process hosts the API, the static admin and uses a YARP proxy to route the root to Next.js SSR. The database is Azure-managed PostgreSQL, media live in Cloudflare R2. Traefik handles reverse proxy and TLS, Cloudflare CDN + WAF absorbs attacks. Azure Pipelines automate CI/CD.

Solution architecture
  1. Users: Visitors (6 languages)
  2. CDN: Cloudflare (CDN · DDoS · WAF)
  3. Proxy: Traefik (reverse proxy · TLS)
  4. Apps: Next.js 16 SSR (public website); React admin (MUI 7 · Vite 8)
  5. Core: .NET 9 API + YARP (ASP.NET Core)
  6. Data: Azure PostgreSQL; Cloudflare R2 (media · WebP)
  7. Integrations: AI & content (Claude API · translations, Google Places · reviews); Sign-in & marketing (Google OAuth 2.0, Ecomail · newsletter, Google Tag Manager)
  8. Deployment: Azure DevOps → CI/CD pipelines → Docker · Azure
04 — Results

Results

3× larger indexed footprint in Google

1,333 URLs in the sitemap versus 539 on the old site. New language variants open up rankings on Google.de, Google.fr, Google.ru and Arabic-speaking markets.

Rich snippets ready

17 JSON-LD structured data types verified in Google Rich Results Test. AggregateRating from imported Google reviews brings star ratings straight to the search results.

Migration without SEO loss

The AI matcher proposed redirects for 97.6% of old URLs. Chain flattening ensures redirects never chain up and link equity stays intact.

6 languages including RTL Arabic

Full SSR across 25 page types in 6 languages — including correct RTL layout for Arabic. Hreflang and x-default on every URL.

Self-service admin across 14 sections

The client manages content without a developer. AI translations into 6 languages run asynchronously in the background, audit trail provides point-in-time recovery, slug changes auto-create redirects.

PPC-ready analytics

Google Consent Mode v2 and value-based conversion events in CZK for Google Ads Smart Bidding. Cookie banner and legal pages localized into all 6 languages.

Technologies

  • .NET 9
  • ASP.NET Core
  • EF Core
  • C#
  • Next.js 16
  • React 19
  • TypeScript
  • Tailwind 4
  • Material-UI 7
  • Vite 8
  • PostgreSQL
  • Docker
  • Azure
  • Azure Container Registry
  • Azure DevOps Pipelines
  • Cloudflare R2
  • Cloudflare CDN
  • Traefik
  • Anthropic Claude API
  • Google Places API
  • Google OAuth 2.0
  • Ecomail
  • Google Tag Manager
  • Consent Mode v2

More case studies

All case studies

Magistra a.s.

Data warehouse on Microsoft Fabric for a 200+ pharmacy chain

DataEnterpriseMicrosoft Fabric
Read more

JUST CS spol. s r. o.

Full replacement of an MLM sales network management system in 3 months

EnterpriseSystem replacementAzure
Read more

Netigo s.r.o.

An application for network traffic collection and reporting supporting NetFlow v5/v9 and IPFIX protocols, with a high-performance storage backend on PostgreSQL + TimescaleDB.

High-performanceDataNetwork
Read more

Related reading

Deeper technical notes on the topics from this case study.

AI & Automation · 7 min read

Claude Batch API for translations: 50% cheaper, but it's a queue

On the translation pipeline for The Clinic Praha we moved from the synchronous Claude API to the Batch API. 50% discount plus prompt caching gets us around 80% savings. The catch is the queue — and a few cases where batch is the wrong call.

Read article
Migration & SEO · 9 min read

Migrating a Laravel website to Next.js 16 + .NET 9 with zero SEO loss

A dental clinic with a two-language Laravel site needed to reach patients in six languages without losing Google rankings. Here's how we did it in three weeks — and how the redirect AI matcher covered 97.6% of old URLs.

Read article
A senior architect on every project · About us →

Want a similar solution?

Send us a message — we respond within one business day and schedule an intro call.