A Website That Follows Spanish Rules: Legal Pages, a Processing Record and a Consent Log
A small business in Spain needs a legal notice, a privacy policy, a cookie policy, a record of processing and proof of every cookie choice. We build all of that into the site itself, so the documents match what the site really does.
The Challenge
Every business website in Spain answers to three laws at once: the GDPR, the Spanish data protection act (LOPDGDD) and the e-commerce act (LSSI-CE). In practice this means a legal notice with the owner’s legal name, tax ID and address, a privacy policy, a cookie policy, a banner that asks before any tracking starts, proof of each visitor’s choice and, behind the scenes, a record of processing activities that an inspector can ask to see.
Most small sites cover this with a policy copied from a generator. Those texts usually describe a different business: wrong providers, wrong retention periods, and the web studio presented as if it were the company answering to the visitor. If the site loads Google Analytics or a Google map before the visitor clicks anything, the banner is decoration.
We wanted every site we build to have documents that describe that exact site, and code that does what the documents promise. The same approach now runs on a handyman business, a car rental company and a barbershop, all on the Costa Blanca.
Legal Pages From One Source
All three legal documents (the legal notice, the privacy policy and the cookie policy) read their facts from a single data file in the site’s code. It holds the two parties and their roles:
- The client is the controller: the business decides why enquiries are collected, and visitors exercise their rights against it. Its legal name, tax ID, address, contact details and, for a company, its registry entry are stated once and appear wherever a document needs them.
- Yatoday is the processor: we build and host the site and run the platform that receives enquiries and stores consent records, acting only on the client’s instructions under a processing contract (art. 28 GDPR). The documents say this plainly and link to our own legal notice and privacy policy instead of repeating our details.
Because the facts live in one place, the three pages can’t disagree with each other. On the handyman site, the same address is also split into street, postcode and town for the business markup Google reads, so the legal notice and the search data always show the same address.
When we start a new site from our template, the data file starts with every required field set to “PENDIENTE DE COMPLETAR” (pending). The placeholder is meant to stand out: a missing tax ID shows up on the page where everyone can see it, instead of hiding behind a made-up number.
The documents are written for each business, not filled in from a generic text. The car rental policy explains the rental contract and the traveller register that Spanish law requires rental companies to send to the Ministry of the Interior. It also states that the site has no forms, so the processor only handles the cookie consent record. The handyman policy describes the quote form step by step: where the request goes, how it is checked for spam, which CRM it lands in and who can see it. Each policy lists the providers that actually touch the data, such as hosting, CDN, email delivery and maps, with their location and the legal basis for any transfer outside the EU. The handyman site publishes its legal pages in Spanish, English and Russian, and states that the Spanish text is the binding one.
The Record of Processing, Kept in Step
Article 30 of the GDPR requires a record of processing activities, known in Spain as the RAT. It is not published, but it is the first document an inspection asks for, and the first place where it finds gaps.
For each site the record sits in the same repository as the legal pages. It lists every processing activity: handling quote requests, carrying out the work and invoicing, spam prevention, the cookie consent log, web analytics, the service-area map and handling rights requests. For each one it gives the purpose, the legal basis, the people and data involved, the recipients and the retention period. It also records reasoning a checker would look for. The consent log, for example, relies on the legal duty to prove consent, not on consent itself. Otherwise, withdrawing consent would mean deleting the proof that consent was ever given.
The first lines of the record say that it must match the published privacy policy. In practice, a change of provider or retention period goes into the record and all three legal pages in the same commit.
A small script turns the plain-text record into a typeset PDF with page numbers, ready to sign or send. It uses the browser engine that is already installed. The PDF is always generated from the text and never edited by hand, so the two versions can’t drift apart.
A Cookie Banner That Means It
The banner comes from our component library and is shared by every site.
Google Consent Mode v2 is set to “denied” for analytics and all three advertising signals before anything loads, that is, before any Google tag can run.
Google itself doesn’t load at all until the visitor agrees. Consent Mode alone would still download Google Tag Manager and trust Google to respect “denied”. Our loader doesn’t request it at all until the visitor clicks “Accept all”, so a visitor who refuses never sends their IP address to Google. You can see it in the clip above: before the click, zero requests to Google. After it, Tag Manager loads and Analytics receives its first hit with analytics granted and advertising denied.
Each site declares what it actually does with cookies, and only the declared purposes can be granted. A site that only measures traffic can never pass advertising consent to Google, even after “Accept all”. With a single purpose, a two-button accept/reject banner is enough under the Spanish data protection agency’s cookie guide.
Every choice leaves proof. The banner generates a random consent ID and sends the choice to our platform, together with the categories, the policy version, the page, the language and the browser. If the visitor later changes their mind, the new choice is added to a history for that ID. A round button in the corner shows the visitor the date and ID of their consent and lets them change it.
Maps Without Cookies
An embedded Google map sets Google cookies before the visitor has chosen anything. On the handyman and car rental sites we replaced it with an OpenStreetMap map, which stores nothing on the visitor’s device. It still exposes the visitor’s IP address to the OpenStreetMap Foundation, so the privacy policy and the record list it as a recipient. It needs no consent gate, because nothing is stored on the device. On the car rental site the map loads its tiles only when it scrolls into view.
Tech Stack
- Sites: Astro (static build), Tailwind CSS 4, @yatoday/astro-ui
- Legal pages: MDX reading one typed data file per site
- Record of processing: plain text in the repository → PDF via headless Chrome (CDP)
- Consent: astro-ui CookieConsent, Google Consent Mode v2, consent-gated GTM loader
- Consent log and history: Yatoday platform API (Laravel)
- Maps: Leaflet + OpenStreetMapResult
Each site ships with a legal notice, a privacy policy and a cookie policy that describe that business and its real providers, with the client named as controller and Yatoday as processor. The record of processing sits next to them in the same repository and becomes a PDF with one command. The cookie banner keeps Google off the page until the visitor agrees, keeps advertising signals off when a site only measures traffic, and stores a dated record of every choice.




