PoorDevelopers
2 min read By Poor Developers

Shipping in two languages without letting English rot

Almost every bilingual site ends up with half a website in stale English. We decided the build should fail before we let that happen, and why that is a product decision rather than a tooling one.

Mockup of a browser window with two columns of text

There is a pattern that repeats in almost every small bilingual site: at first everything gets translated, three months in only the important things do, and a year later there is an English version with four pages from 2023 and a menu pointing at routes that no longer exist.

It is not for lack of willingness. It is that translating is optional work, and optional work always loses to work that is not.

What we did

Make it not optional. The build fails when an entry exists in one language but not the other:

✗ Translation parity: 1 problem(s)

  · blog/dos-idiomas: missing the "en" version (present in: es).
    Create src/content/blog/en/<slug>.md with the same id.

There is no way to deploy half-translated. It ships in both languages or it does not ship.

Pairing is not by filename

This is the detail that makes the idea survive contact with reality. If you pair translations by filename, you force the slug to be identical in both languages — and then either the Spanish carries English slugs or the English carries Spanish ones. Both are bad for readers and for indexing.

Every entry carries a stable id, and the slug is free:

src/content/blog/es/dos-idiomas.mdx      → id: dos-idiomas
src/content/blog/en/keeping-english.mdx  → id: dos-idiomas

They share an id, so the language switcher knows how to keep you on the same page instead of dumping you on the home page, and hreflang generates itself.

What it costs

A post costs twice the writing. That is real and we are not going to dress it up: we have published less because of this rule.

We accept it because the opposite failure is worse. A site that is half stale English does not read as bilingual, it reads as abandoned — and that impression spreads to everything else, including the apps that do work.

If it ever genuinely blocks us, the way out is marking an entry monolingual explicitly. What we are not going to do is quietly relax the check, which is how every site that ends up that way begins.

esc