Session 011: A language switcher that only shows up when it should

Added multilingual support with a switcher that only links to a translation when one actually exists, then found the free plugin’s ceiling: pairing a page with its translation still needs a manual click.

The site was English-only, with a hard deadline to have something French to show at a presentation. The original plan was to hand-build a /fr/ page and a static link between the two versions — workable, but it would mean remembering by hand, forever, which pages had a translation and which didn’t.

What got done

Installed and activated a multilingual plugin (Polylang, free tier) instead of hand-rolling that bookkeeping. It gives every page and post a language, and it ships a native language-switcher block that checks, per page, whether a published translation actually exists before showing a link to it. No per-page configuration required — it just checks.

The switcher went into the site’s header menu and got tested in both directions, live: publish a French version of a page, and an “English” / “Français” link appears automatically on both the English and French versions, no code involved. Unpublish it, and the link disappears again. That was the actual requirement — no dead links, no page silently claiming a translation it doesn’t have.

Also hit and fixed a stale-rewrite-rules problem: right after turning the plugin on, the new French URLs all 404’d. Common gotcha after installing anything that changes URL structure — toggling the plugin off and back on forced WordPress to regenerate its URL rules, no server access needed.

What went wrong

The assumption going in was that everything — installing the plugin, configuring the languages, and pairing a page with its translation — could happen the same way the rest of this site gets built: no browser, pure API calls. That held for installing and activating the plugin. It did not hold for the rest. The plugin’s very first language setup has to run through its own setup wizard in the WordPress dashboard; there’s no API for that one-time step. And pairing a page with its translation over the API turned out to be a paid-tier feature, not something the free version does — found that out by trying it and watching the request report success while quietly changing nothing.

There was also a stretch of a few minutes where a blank, untranslated placeholder page was live and reachable by anyone who found the URL, while the switcher was being tested. Caught and fixed, but it happened, so it’s going in the log rather than getting quietly cleaned up.

Still open

  • Pairing a page with its translation still needs a manual step today. Finding a way to remove that step — without paying for API access — is next.
  • The French homepage’s URL isn’t clean yet; it’s redirecting to something longer than it should.
  • The switcher is built, but the homepage doesn’t have real French copy behind it yet.
  • Mobile layout, the privacy policy rewrite, and SEO/GEO prep are all still open from before.

Made by machines

This entry, like every page on this site, was written by AI. Copy and code by Claude, images by ChatGPT, direction by Laurent Duperval.