I Built a Multilingual Cultural Encyclopedia That Uses Zero Cookies. Here's How.
Today is World Cat Day 🐾, and I wanted to celebrate by sharing a project I've been quietly building: a privacy-first, multilingual cultural encyclopedia about cats and the cultures that love them.
It's called meow.hair, and it now covers 13 cultures across 8 languages — with absolutely no cookies, no tracking, no ads, and no donations.
Why Cats? Why Culture?
Every culture has a unique relationship with cats. In Finland, cats were believed to be born from the warmth of the sauna. In Mexico, the word "Michi" carries centuries of linguistic history. In Japan, cats are spiritual guardians. In Hungary, they protected the banks of the Danube.
I wanted to tell these stories with the respect they deserve — in their native languages, with local sources, and without turning readers into data points.
The Core Principle: Respect Users Like Cats Respect Their Territory
I built this site on a simple philosophy:
- No cookies — not even for analytics
- No tracking — no pixels, no beacons, nothing
- No ads — the content speaks for itself
- No donations — this is a personal effort, not a business
- No frameworks — just HTML, CSS, and vanilla JavaScript
The entire site is a single-page application hosted on Vercel's free tier, using only system fonts and lazy-loaded images. It loads fast because it has nothing to hide.
Technical Highlights
1. Multilingual SEO Without Duplicate Content
One of the trickiest parts was telling Google about 13 different language versions without triggering duplicate content warnings. I solved this with hreflang tags:
<link rel="alternate" hreflang="es" href="https://meow.hair/" />
<link rel="alternate" hreflang="en" href="https://meow.hair/canada-meow.html" />
<link rel="alternate" hreflang="fi" href="https://meow.hair/cat-finland.html" />
<link rel="alternate" hreflang="hu" href="https://meow.hair/meow-magyar.html" />
<link rel="alternate" hreflang="x-default" href="https://meow.hair/" />
The x-default fallback is crucial — it tells search engines where to send users whose language isn't explicitly covered.
2. Schema.org for Rich Results
I added structured data so search engines can display rich snippets:
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Michi: The Word That United a Continent",
"datePublished": "2026-03-15",
"dateModified": "2026-08-08",
"author": {
"@type": "Organization",
"name": "meow.hair"
}
}
3. Local-Only Storage Instead of Cookies
For the few interactive features I needed (like a copy counter), I used localStorage so nothing ever leaves the user's device:
let count = localStorage.getItem('meowCopy')
? parseInt(localStorage.getItem('meowCopy'))
: 0;
// The counter lives only in the browser. No server involved.
localStorage.setItem('meowCopy', count);
4. Privacy-Protected Contact
Instead of displaying my email address openly (which would get scraped by bots), I hide it behind a button:
<button id="showEmailBtn">📧 Show email</button>
<div class="email-box" id="emailBox" style="display:none;">
<a href="mailto:worldday@mailo.com">worldday@mailo.com</a>
</div>
function toggleEmail() {
emailBox.style.display = emailBox.style.display === 'none' ? 'block' : 'none';
if(emailBox.style.display === 'block') {
emailBox.scrollIntoView({behavior: 'smooth'});
}
}
5. Accessibility Is Not Optional
I added support for users who prefer high contrast or reduced motion:
@media (prefers-contrast: high) {
body { background: #000; color: #fff; }
}
@media (prefers-reduced-motion: reduce) {
* { animation: none !important; transition: none !important; }
}
*:focus-visible {
outline: 2px solid var(--text);
outline-offset: 2px;
}
And I included a text-to-speech feature so anyone can listen to the articles:
document.getElementById('readBtn').addEventListener('click', function() {
if (!window.speechSynthesis) return;
const txt = document.getElementById('storyText').innerText;
const utterance = new SpeechSynthesisUtterance(txt);
utterance.lang = 'es-ES';
utterance.rate = 0.9;
window.speechSynthesis.speak(utterance);
});
Design: Why Black and White?
The entire site uses a two-color palette:
:root {
--bg: #0a1929;
--text: #ffffff;
--border: #ffffff;
}
I chose this for three reasons:
- It respects attention. No colorful distractions pulling you away from the content.
- It prints beautifully. The academic-style layout looks great on paper.
- It loads instantly. No heavy assets, no web fonts, no CDN calls.
What I Learned
Building this project taught me several things:
- Privacy and usability are not opposites. You can have a rich, interactive experience without tracking anyone.
-
Multilingual content is harder than it looks. Proper
hreflangtags, localized URLs, and culturally accurate translations take real effort. - Simplicity scales. A single HTML file with no dependencies is easier to maintain than a complex framework.
- Cats are great project managers. They remind you to take breaks and appreciate the little things.
An Open Invitation
If you're building privacy-first projects, cultural content, or anything in between, I'd love to hear from you:
- What privacy techniques do you use in your projects?
- How do you handle multilingual SEO?
- Have you found good alternatives to cookie-based analytics?
Let's share ideas and build a web that respects its users.
Links
- Live site: meow.hair
- Bluesky: @now2026new.bsky.social
Built with love for cats and cultures. No cookies were harmed in the making of this site.
Thank you 😁😸🤍🌊🧊🗻
webdev #privacy #accessibility #seo #html #css #javascript #culture #webdesign
Top comments (0)