GDPR Compliance for Websites: What It Actually Takes to Build One
Most GDPR advice online is written for lawyers or for people buying a policy generator. Very little of it is written for the person who has to open an editor and change something.
This guide is the second kind. It walks through what the General Data Protection Regulation asks of a website and the systems behind it, expressed as things you build, configure or delete. We have been doing this work for companies operating in the EU since the regulation applied in 2018, and the pattern of what goes wrong has barely changed in that time.
One thing to say up front: GDPR did not get easier because newer regulations arrived. It got more important, because almost everything in the current wave of EU digital rules assumes you already have your personal data house in order.
Start With an Honest Data Inventory
Nearly every failed GDPR project we have inherited failed at the same place. The team wrote the policy first and discovered the data later.
Before anything else, map what personal data your site actually collects. Not what the product spec says it collects. What is in the database, the logs, the analytics platform, the CRM, the support tool, the marketing automation stack, the error tracker, the CDN logs and the third-party scripts on the page.
In practice that means:
- Grep the schema. Every column that could identify a person, directly or in combination with another column.
- Read the network tab on a real page load. Every outbound request to a domain you do not control is a potential transfer of personal data, because an IP address plus a user agent is personal data.
- Check what your error tracker captures. Stack traces routinely contain email addresses, tokens and request bodies.
- Check log retention. Access logs with IPs kept forever are one of the most common findings and one of the easiest to fix.
Write it down as a record of processing activities. Article 30 requires it for most organisations anyway, and the version that is useful to engineers is a table with the system, the data, the purpose, the lawful basis, the retention period and the recipients.
Pick a Lawful Basis Per Purpose, Not Per System
Article 6 gives you six lawful bases. The mistake we see most often is choosing one for the whole product.
You almost certainly have several purposes running at once. Fulfilling an order is contract. Fraud checks are usually legitimate interests or legal obligation. Keeping invoices for the statutory period is legal obligation. Marketing email is consent in most Member States. Non-essential analytics is consent, because of the ePrivacy rules on terminal equipment access rather than GDPR itself.
The practical consequence is that your data model needs to know which purpose each record serves. If you cannot separate the marketing profile from the order record, you cannot honour a marketing objection without breaking order history. That separation is a schema decision, and it is painful to retrofit.
Consent Has to Be Real, and It Has to Be Recorded
If you rely on consent, it has to be freely given, specific, informed and unambiguous, and you have to be able to demonstrate it later.
Concretely:
- Nothing non-essential fires before the user acts. That includes the analytics snippet, the ad pixel, the chat widget, the font loaded from a third-party CDN and the A/B testing script.
- Reject must be as easy as accept. Same layer, same prominence, same number of clicks. Regulators treat anything else as a dark pattern, and they have been consistent about it.
- Consent is per purpose. One toggle covering "analytics and marketing and personalisation" is not specific.
- Withdrawal is as easy as granting. A persistent link or a floating button, not an email to support.
- Store the proof: a timestamp, the consent string or the state of each category, the banner version, and the text the user was shown. Without the version, you cannot defend a two-year-old consent record.
The enforcement here is not theoretical. In September 2025 the French data protection authority fined Google 325 million euros and Shein 150 million euros over cookie practices on the same day. Both cases turned on mechanics rather than on policy text: cookies dropped before any interaction, and reject buttons that did not actually reject.
The rules around this are also in motion. The Digital Omnibus proposal would move terminal equipment consent into GDPR itself and make browser-level signals binding. We covered what that would change in cookie consent after the Digital Omnibus.
Build the Data Subject Rights Machinery Early
Articles 15 to 22 give people the right to access, rectify, erase, restrict, port and object. You have one month to respond, extendable to three in complex cases.
Teams tend to handle the first few requests manually, which works right up until it does not. What you want, well before volume arrives:
A resolver that finds a person across systems. Given an email address, return everything: the account, the orders, the support tickets, the marketing profile, the analytics identifier, the logs. If a human has to remember that there is a third-party review platform holding data, someone will eventually forget.
A deletion path that respects retention obligations. Erasure is not absolute. Invoices usually have to survive for tax reasons. What you need is soft deletion with purpose-scoped hard deletion, so you can remove the marketing profile while keeping the accounting record, and so the accounting record itself expires on schedule.
A portable export. Structured, commonly used, machine readable. JSON is fine. A PDF of a rendered HTML page is not.
An objection flag that the whole system reads. Objecting to profiling has to actually stop the profiling, including in the batch job that runs at 3am and does not check the flag.
Retention Is a Job, Not a Policy Line
Storage limitation is the principle most often violated by systems that are otherwise well built, because deleting data requires someone to write and schedule a job that nobody asks for.
Give every data category a defined lifetime, then implement it. Access logs, session records, abandoned carts, unverified signups, closed support tickets, old backups and analytics raw data all need an expiry. Backups deserve particular attention: if your restore process resurrects deleted personal data, your erasure is incomplete, and the usual answer is documented backup rotation with a maximum age plus a re-application of deletions after any restore.
Transfers, Sub-Processors and Where Your Stack Actually Runs
Transfers outside the EEA need a legal mechanism, usually the EU-US Data Privacy Framework for certified US recipients or Standard Contractual Clauses plus a transfer impact assessment elsewhere.
The engineering angle is simpler than the legal one: know where your data physically is. That means the cloud region for every service, the location of your backups, the region of your managed database, the CDN edge configuration and, importantly, the support model of every SaaS tool you use. A vendor hosted in Frankfurt whose support team accesses production from outside the EEA is still a transfer.
We generally recommend keeping personal data in EU regions when there is no strong reason not to. It removes an entire category of argument, and the cost difference is usually noise.
Maintain a sub-processor list and keep it current. Article 28 requires a written processing agreement with each one, and the list is also what your customers will ask for in due diligence.
Security by Default, Expressed as Configuration
Article 32 asks for appropriate technical and organisational measures. That is deliberately vague, but the baseline for a website in 2026 is not:
- TLS everywhere, HSTS enabled, no mixed content.
- Passwords hashed with a modern memory-hard function, and multi-factor authentication available for accounts holding personal data.
- Encryption at rest for databases and backups.
- Access to production personal data limited by role and logged, with reviews that actually happen.
- Pseudonymisation where it is possible: hash the identifier in analytics, keep the mapping table separate and access-controlled.
- A tested restore, not just a backup.
Data protection by design and by default in Article 25 means the privacy-preserving option is the one you get without doing anything. Newsletter checkbox unticked. Profile visibility private. Optional fields optional.
Breach Notification Needs a Runbook
Seventy-two hours from awareness to notifying the supervisory authority is not long, especially if the breach is discovered on a Friday evening. Note that the Digital Omnibus proposal would move that to ninety-six hours, though it is not law yet.
Prepare in advance: who declares an incident, who assesses whether personal data was affected, who contacts the regulator, what the notification contains, and how you tell affected people if the risk is high. Write it as a runbook with named roles, and rehearse it once. The first time you use it should not be the first time you read it.
The Website Surface Itself
Some of GDPR is visible on the page, and it is worth getting the details right because these are the things people report.
Your privacy notice needs to state the controller identity and contact, the purposes and lawful bases, recipients and categories of recipients, transfer mechanisms, retention periods, the full list of rights including the right to complain to a supervisory authority, and whether there is automated decision-making. Write it in language a normal person can follow. Layered notices, with a short version linking to detail, work better than a wall of text.
Forms should collect only what you need. Every field is a justification you may have to make. If the marketing consent checkbox is on the same submit as the order, it needs to be separately unticked and separately worded.
Third-party embeds are the quiet failure. YouTube in privacy-enhanced mode, maps behind a click-to-load placeholder, fonts self-hosted rather than pulled from a third-party CDN. Each of these is a small change and each one removes a finding.
What We See Go Wrong Most Often
After enough audits, the same short list keeps appearing:
- Analytics loading before consent, usually because a tag manager was configured by marketing and never reviewed by engineering.
- Reject buttons that fire consent anyway because of a third-party script's default behaviour.
- No retention jobs at all, on any table.
- Erasure that misses backups, logs and the CRM.
- A privacy notice describing a data flow that changed eighteen months ago.
- Sub-processor lists that stop at the obvious three vendors.
- Consent records with no version of the text that was shown.
None of these are hard problems. They are just work that nobody has been assigned.
Getting Help
If you want a second pair of eyes on an existing site, we do technical GDPR audits that produce a prioritised backlog rather than a report: what to fix, in what order, with an estimate against each item. If you are building something new, it is considerably cheaper to get the data model and consent architecture right at the start.
We also handle the wider EU compliance surface, including accessibility and European market entry. Reach us at office@c9group.dev.
We build software. We do not give legal advice, and the interpretation of any specific requirement belongs to your counsel. What we can do is make sure the system does what your counsel says it should.