Skip to content

1.0.0 — Multi Domain Language Switch

Latest

Choose a tag to compare

@pvollenweider pvollenweider released this 09 Sep 12:50
· 1 commit to main since this release
2ba390f

First release of the module as a Jahia community bundle.

It binds each language of a site to its own domain — something Jahia does not
support natively, because a hostname resolves to a site while the language
lives in the URL path. See
Why this module exists.

Requires Jahia 8.2
Optional site-settings-seo, for the hreflang and canonical rewriting
Licence MIT
Configured in Administration → Sites → Language URL mapping
Scope live mode only — edit and preview are untouched by design

What it does

  • A droppable menu component (lsm:domainSwitchLanguage) whose links each
    carry the hostname registered for their language. Labels are endonyms,
    lang and hreflang are BCP 47, the current language gets aria-current
    plus a non-colour indicator.
  • A per-language redirect: requesting a page in a language mapped to
    another host answers 302 to the same path on the right host. It decides on
    the resolved locale of the rendered resource, never on the shape of the
    incoming URL, so vanity URLs are preserved rather than replaced by a
    technical render path.
  • SEO head elements: the hreflang alternates and the canonical link
    produced by site-settings-seo are rewritten to the host mapped to each
    language, so a multi-domain multilingual site stops telling search engines
    that every language lives on one host.
  • A site settings panel to enter one base URL per site language, guarded by
    the siteAdminLanguageUrlMapping permission. UI texts ship in the six
    standard Jahia UI languages.

The mapping does not have to be one domain per language: several languages can
share a host while others get a dedicated one.

Installing

Drop multi-domain-language-switch-1.0.0.jar into digital-factory-data/modules/,
then enable the module on the site. Every mapped hostname must be declared on
the site as its server name or in j:serverNameAliases, and must resolve to the
Jahia instance.

To use the component from your own module, or to restyle it, read
INTEGRATION.md.
Setup questions — which port to put in the mapping, behaviour behind a CDN,
testing several domains locally — are answered in
FAQ.md.

Security

The base URLs stored on the site node end up in the href of every menu link
and head element of a live page. They are parsed and rebuilt from their scheme,
host and optional port, which makes an attribute break-out unrepresentable
rather than filtered — and the check runs when reading as well as when saving,
because the property can also be written by an import, a migration or a script.
SECURITY.md describes the boundary; tests/cypress/e2e/09-mapping-injection.cy.ts
is the regression test.

Accessibility

Targets WCAG 2.2 AAA, with one boundary stated openly: the menu imposes no
colour and no font by design, so text and background contrast is the
integrator's to verify. Everything the module can guarantee without knowing
your palette — a focus indicator drawn in the inherited text colour, a 44px
target, non-colour state indicators, list semantics, BCP 47 language
attributes — it does. The split is tabulated in INTEGRATION.md.

Quality

  • 100 unit tests, 97.3% coverage (98.4% by line)
  • 64 Cypress integration tests against a real Jahia 8.2.3.2, over a network of
    four hostnames, covering the menu, the redirect, vanity URLs, shared domains,
    the SEO head elements, edit mode, the settings panel and the admin UI locale
  • SonarQube quality gate passing: 0 bugs, 0 vulnerabilities, 0 code smells,
    ratings A/A/A, 0% duplication

Known limitations

  • The mapping value is a scheme, a host and an optional port. A path is
    dropped: both filters compare and rewrite on host and port only.
  • An internationalised domain must be given in punycode, and a hostname
    containing an underscore is refused — both consequences of strict URI parsing.
  • The redirect answers 302, not 301, so it does not by itself declare a
    canonical domain. The rewritten canonical link does that.
  • Behind a proxy or CDN that terminates TLS, the container must report the
    client scheme and port, or the host/port comparison produces a redirect loop.
    See the FAQ.