German-market-ready is a shape of work, not a checkbox.
The standard pitch for "we are GDPR-ready" tends to mean an Impressum dropped into a footer and a cookie banner bolted on by a script tag. Real compliance is not a label. It is a set of shapes that constrains where code lives, how consent is framed, how URLs are structured, and what headers leave the server.
We did that work on this site. This is the honest tour — what we built, where the choices sat, and which of the calls we would make the same way again. The short version: most of it was the good kind of work, the kind that compounds.
The URL matters
There are two common ways to serve a bilingual site. One puts the locale in a cookie and swaps the language on the same URL. The other puts the locale in the path — `/de` and `/en` — and never lies about which language a given address speaks. We picked the path. It is the only option that lets a search engine index both variants cleanly, that lets a reader share a German link and trust that the recipient will land on the German page, and that lets the site's sitemap emit proper hreflang alternates instead of pointing every variant at the same origin.
The detail that closes the loop is `x-default`. If you do not set it, the search engine picks for you. We point `x-default` at the German URL because Germany is the primary market and the site's center of gravity reads German first. That is a one-line choice in the sitemap generator, and it is the kind of choice that signals market intent before anyone reads a word of copy.
Consent is a legal basis, not a banner UX problem
Two laws sit behind the cookie banner on this site. §25 TTDSG governs storage and access on the device — the moment something is written to or read from the browser beyond what is strictly necessary for the service the user asked for, you need consent. Art. 6(1)(a) DSGVO governs the personal data that is then processed on the basis of that consent. They stack. A single click has to carry both.
The banner has to do a few things at once: name concrete purposes, list vendors when you know them, avoid pre-checked boxes, and — the one that most implementations get wrong — present "Accept all" and "Reject all" at equal visual weight. Not because a guidance document says so, but because the entire design principle of consent collapses if the rejection path is harder than the acceptance path. A consent you only give because the alternative is friction is not a consent you gave.
The part that keeps a banner honest over time is the reopen path. A user who clicked once six months ago has to be able to revisit the choice without hunting for it. On this site that lives as a persistent footer link and a standing settings surface on the cookie policy page — two entries into the same state, both always available.
- No pre-checked boxes for anything beyond strictly necessary.
- "Accept all" and "Reject all" at equal visual weight, same click depth.
- Purposes named in plain language, not legalese.
- Vendors listed by concrete name when known, not hidden behind a category.
- Reopenable from a persistent footer link and from the cookie policy page.
Impressum is a structural commitment
§5 TMG and §18 MStV are short laws with specific demands. Provider identification, named representation, the register and VAT entries, a contact path, and a "responsible for content per §18 MStV" line that names a human being. Drop-in templates always miss something — the EU ODR link that links to the right Commission page, the VSBG statement about whether you participate in consumer arbitration, a liability-for-links clause that reads the way a court expects it to read.
We structured the Impressum page as real sections, each mapped to the law it satisfies, so that dropping the final entity details in becomes a ten-minute task instead of a scramble. The page shape is the promise; the data lives in a single config.
If the page structure is right, dropping real data in is a 10-minute task. If it is wrong, you find out during an audit.
The part everyone forgets: response headers
A surprising amount of real compliance lives in the four or five bytes of header at the top of every response. Strict-Transport-Security with a two-year max-age and `preload`. Referrer-Policy at `strict-origin-when-cross-origin` so path and query do not leak across origins. Permissions-Policy that denies the powerful features the site does not use — camera, microphone, geolocation, browsing-topics. And a real Content-Security-Policy, with a per-request nonce on script-src, `strict-dynamic` so nonced roots can load what they need, and a report collector at a first-party endpoint.
We ran the CSP in Report-Only for a week before flipping it to enforcing. Not because we were guessing — because observing is cheaper than unbreaking. The header flip is one line; the confidence that comes from a week of real traffic with zero genuine violations is the part worth having.
Report-Only is the closest software engineering gets to dress rehearsal.
Operationally: email, forms, and the data you don't keep
The contact form carries an Art. 13 notice inline — a short sentence that names the purpose, links to the privacy policy, and makes clear that the submission is used to reply and nothing else. The careers page takes the simpler shape: email in, email out, no applicant-tracking system, no third-party recruiting tool in the chain. If you did not build a system to hold the data, you cannot leak the data you do not hold.
Underneath both surfaces sit the baseline hygiene pieces: a per-IP token bucket so a single actor cannot flood the endpoint, a honeypot field that silently discards the obvious bots, input validation that rejects bad shapes at the edge. None of that is exciting. All of it is the reason the production inbox stays usable.
German-speaking is a feature, not a translation job
There is a difference between a German page and a page translated into German. The German page uses the Sie-form throughout without apologizing for the register. It uses the terms that only read right if you have worked in the market — "Anbieterkennzeichnung", "Vertretungsberechtigte Person", "Haftung für Links", "Widerspruchsrecht". It leaves the tech words in English where they belong (Cookie, Header, Release, CSP) and keeps the legal words in German where they belong (DSGVO, TTDSG, Impressum).
Machine translation gets ninety percent of a DSGVO page and embarrasses you on the remaining ten. The remaining ten is every place where the word choice carries a legal weight that does not survive a round-trip through a general-purpose model. That work is senior writing, done once, carefully.
What this buys you
The work described here is not a one-time project; it is a surface. A surface that ages well because the pieces reference each other cleanly — the sitemap iterates the same insights registry the feeds iterate, the Impressum sections mirror the statute they satisfy, the CSP report endpoint is a first-party route inside the same build. A surface that passes audits without a scramble because the checks are what the site is, not what the site owner puts on in front of the auditor. And a surface that signals to the German market that you showed up serious.
Most of this is the good kind of work — the kind that compounds.