A travel website in 5 languages, no plugins: lessons learned

My website runs in five languages — Spanish, English, French, Catalan and Italian — without WordPress, translation plugins or a monthly fee: static HTML, one URL per language and a handful of rules learned along the way, some the hard way. This article is not theory: it is the list of decisions I would make again and the mistakes you can skip if you are about to internationalise the website of a hotel, an agency or any travel business.
Why "plugin multilingual" falls short
The usual route — installing a translation plugin on WordPress — solves the text and tends to ignore what actually ranks. The typical gaps: untranslated or auto-generated URLs, incomplete or missing hreflang tags, a sitemap without the language versions, and machine translation published unreviewed. The result shows up weekly on travel websites: the French version exists, but Google shows the Spanish one to French users — or worse, treats both as duplicate content.
Multilingual is not a translation problem. It is an architecture problem with a translation layer on top.
The four decisions that matter (in order)
1. One URL per language, decided before publishing. Each language lives in its subdirectory (/en/, /fr/, /ca/, /it/) with the main language at the root. No selectors that swap the text without changing the URL: if two languages share a URL, only one exists for a search engine. And this decision is of the irreversible kind: changing URL structure later requires permanent redirects, and not every hosting allows them — mine, for instance, doesn't, so every slug was chosen knowing it was forever.
2. Translated slugs, not just translated text. The English services page should not live at /en/servicios/ but under its English form. The slug is part of the content: users (and machines) read the URL. This forces you to keep a map of equivalences between languages — a small ordering cost paid once.
3. Reciprocal hreflang with x-default. This is the part most websites get wrong, and the most mechanical: each page lists all its language versions, including itself, plus a default version (x-default) for users who fit none. The golden rule is reciprocity: if the Spanish page claims an Italian version exists, the Italian one must claim the Spanish one exists. Half-done hreflang confuses more than none. And the sitemap must tell the same story: every URL with its full group of alternates.
4. Translation with human review, prioritising the money pages. Modern machine translation is an excellent, cheap first pass. Publishing it unreviewed on the pages where money is at stake — rates, cancellation policies, terms — is another matter: a mistranslated nuance is a complaint waiting for a date. My review order: terms and booking first, then sales pages, editorial content last.
What the no-plugins approach saved me
By serving static HTML generated by my own script, the four rules above don't depend on a plugin honouring them: they live in the code that generates every page, always the same, in all five languages at once. Adding the fifth language (Italian) meant translating content and regenerating; the hreflang, sitemap and URLs came out by themselves. Monthly maintenance cost is zero; the domain and the server are paid separately, once a year. And maintaining five languages costs exactly the same as maintaining one. There is also a side effect that was never in the plan: serving static HTML is exactly what AI crawlers read best, because they do not execute JavaScript — I go through it point by point in the 7-point checklist.
I am not arguing everyone should abandon WordPress — that would be bad advice. I am arguing for the criterion: whatever your tool, demand that it fulfils the four decisions above, and check it yourself (hreflang tags are visible in any page's source code; looking is free).
The conceptual mistake
There remains the strategic error, which is not technical: adding languages you cannot maintain. Every language is a promise — that rates will be current, that the cancellation policy will say the same as in Spanish, that someone will be able to handle the enquiry arriving in that language. An abandoned German version with prices from two seasons ago is worse than none: it generates mistaken bookings and justified complaints.
The right question before adding a language is not "will it bring traffic?" but "can I keep the promise?". In my case, five languages are sustainable because the system regenerates everything at once and the content changes little. For a hotel with weekly rates and offers, two well-maintained languages are worth more than five half-done. In multilingual, as in most things digital, ambition is measured in years of maintenance, not in flags on the menu.

