Joomla Multilingual Sites
|
This content was generated with the assistance of AI and should be verified against the official Joomla documentation before being relied on in production. This sub-section’s Joomla bibliography lists the reference material consulted while preparing these pages. |
Joomla has had built-in multilingual support since 1.6, and it is one of the reasons the system is chosen for public-sector, club, university and company sites that must publish in several languages. This page explains the whole mechanism from the site builder’s screens down to the system plugin that decides which language a request is served in: language packs and content languages, the System - Language Filter and System - Language Code plugins, one Home menu item per language, the Language Switcher module, associations between translations of articles, categories, menu items, contacts, news feeds and modules, the Multilingual Status module, language overrides and, new in Joomla 6.2, language fallbacks.
The page was checked against the official documentation and the 6.2 source tree on 2026-10-30. It refers to Joomla 6.2 (the current release, requiring PHP 8.3 or newer). The multilingual machinery is stable across 4.x, 5.x and 6.x, and the text marks the few differences. Joomla 5.4 only receives security fixes, and Joomla 4.x and 3.x are end of life (see Versions, Release Cycle and Support).
The examples belong to the Tallpine Hiking Club, a fictitious mountain club described in
Joomla Introduction and Architecture. Its site is published in
English (the default language, en-GB) and German (de-DE), and every trail report exists in both languages.
What Joomla translates and what it does not
Installing a language pack translates the interface that Joomla and its extensions ship with: button labels, form labels, error messages, the names of core modules and the text of core layouts. It does not translate anything an editor types. The titles, texts, menu items, categories, module titles and custom field values of the site must be written once per language. Joomla offers four tools for managing that content:
| Tool | What it does |
|---|---|
Content language |
A record (table |
Language Filter plugin |
Switches multilingual mode on. It puts a language prefix in URLs, detects the visitor’s language, restricts menus, modules
and content to the active language and adds |
Associations |
Links the translations of one piece of content (rows of table |
Language overrides |
Replace single interface strings without editing the language files that updates overwrite. |
Joomla itself is the only part that can be installed in a language by pressing a button. A site with two languages is therefore a site in which every menu, module and category exists twice, and the work of the site builder is to keep the two trees symmetrical. The diagram below summarises how a request becomes a page in one language, and how the associations are used to build the switcher links. The sections that follow explain each step.
Requirements and prerequisites
Before enabling anything, a site needs:
-
At least one language pack installed besides the default one. Language packs are installed from System > Install > Languages, which lists the packs published by the Joomla translation teams. Installing a pack for a language makes it available for the site front end, the administrator, or both (each pack contains both parts).
-
A published content language for every language that will be used on the front end.
-
A Home menu item (Default Page) for every content language, plus a Home item whose language is All. Joomla’s multilingual status check flags a site that lacks one.
-
A menu, a menu module and a category for each language, named so that editors can tell them apart.
-
A plan for the URLs: the default Language Filter behaviour puts the language prefix in every URL, so Search Engine Friendly URLs must be enabled in the Global Configuration (see SEO, SEF URLs, Redirects and Schema.org).
The only mandatory PHP and database requirements are the ones of Joomla itself (see Requirements and Hosting). The multilingual features add no extension and no special database engine, but multibyte string support must be present for languages with non-Latin scripts, which the Joomla requirements already demand.
Installing languages
Installing a language pack
A language pack is an installable extension of type language. The steps for German are:
-
Open System > Install > Languages (in the Joomla 5 and 6 administrator the page is titled Install Languages).
-
Choose German (DE) (or the regional variant needed, for example German for Switzerland or Austria, when the translation team publishes one) and press Install.
-
Joomla downloads the package and installs it as German (DE-CH) style entries of the type Language. The extension then appears in System > Manage > Extensions and in System > Manage > Languages.
The same page lets an administrator update installed packs. A language pack follows the major and minor version of Joomla,
so after updating Joomla to a new minor release the translation packs should be updated too, otherwise newly added strings
are shown in English. When a language is missing a string, Joomla loads en-GB first and the active language afterwards,
so the visitor sees the English text rather than a raw constant (the load order is described under
the section Language overrides).
Because an installed language pack contains both the Site and the Administrator parts, installing it does not change anything a visitor sees. The two defaults are chosen separately.
Installed languages and default languages
System > Manage > Languages is the list of installed languages, with two tabs:
-
Site: the languages of the front end. The star marks the default site language, used by every visitor for whom no other language is chosen. The default site language is the one the Language Filter plugin falls back to.
-
Administrator: the languages of the back end. The default administrator language applies to every administrator who did not choose a language in their user profile.
Each user can pick a Backend Language and a Frontend Language (and a time zone) in their account, under Basic Settings. The front end language choice only has an effect on a multilingual site (see the section Automatic language change). A site can be administered in English while its public pages are in German, and the other way around.
Other toolbar buttons of the Installed Languages list are Options (including the Language Fallback tab described under the section Language fallbacks (Joomla 6.2)) and Switch Language, which switches the active language of the administrator for the current session.
Content languages
The Content Languages manager
System > Manage > Content Languages lists the languages that content can be written in. A content language is a row of
the table #__languages, and it is separate from the installed language pack: a pack is the interface translation, a
content language is the home of the content. A site may install many packs for administrators and publish only two content
languages for the public.
Pressing New opens the form. The fields come from the file administrator/components/com_languages/forms/language.xml:
| Field | Meaning |
|---|---|
Title ( |
The name in English, for example |
Title Native ( |
The name in the language itself, for example |
URL Language Code ( |
The segment placed at the start of every URL of the language, for example |
Image ( |
The flag image, for example the one for |
Language Tag ( |
The Joomla language tag, for example |
Status ( |
Published, unpublished or trashed. Only published content languages are offered by the filter, the switcher and the language selector of items. |
Access ( |
The access level that may see the language. A language limited to Registered is hidden from guests in the switcher and in the alternate links, which is how a members-only translation is prepared before it goes public. |
Description ( |
A free internal description. |
Metadata Description ( |
The default meta description used by pages of this language when the page does not set its own. |
Site Name ( |
A translated site name that replaces the Global Configuration Site Name when the language is active. |
The Tallpine content languages are:
| Title | Language Tag | URL Language Code | Image | Site Name |
|---|---|---|---|---|
English (UK) |
|
|
|
Tallpine Hiking Club |
Deutsch (Deutschland) |
|
|
|
Tallpine Wanderverein |
The first row of the list, ordered by the Ordering column, defines the order in which the Language Switcher module shows the languages and which language is treated as the first content language. The list can be reordered by dragging.
Ordering of the work
Everything that follows depends on the content languages being published, so the list is the first thing to check when a language "disappears". The Language Filter plugin raises an error when it is enabled and no content language is published, and the Multilingual Status module (see the section The Multilingual Status module) reports the published, unpublished and trashed state of every content language.
Source: Joomla User Guide: Languages
The Language Filter plugin
What it does
System - Language Filter (plg_system_languagefilter, class Joomla\Plugin\System\LanguageFilter\Extension\LanguageFilter)
is the switch that turns a Joomla site multilingual. As a system plugin it subscribes to the application events and to the
site router, and it does five things:
-
It adds a parse rule and a build rule to the site router, so that URLs carry the language prefix (
/en/trails) and a request is assigned to a language. -
It decides the language of a request that has none, from a cookie or session value, the browser or the default language (see the section How the language of a request is decided).
-
It filters content: with the plugin enabled the application is in multilingual mode, and queries for menu items, modules, articles and other language-aware items keep only the current language and All.
-
On each front end page it adds
<link rel="alternate" hreflang="...">tags to the head, and anx-defaulttag, using associations to find the equivalent page. -
It remembers the language in a cookie or in the session.
Enabling the plugin is a prerequisite for everything else on this page. The Multilingual Status module reports whether it is enabled, and the Multilingual Associations component refuses to create associations unless the site is multilingual and the plugin’s Item Associations option is on.
The options
The options are defined in plugins/system/languagefilter/languagefilter.xml, with these defaults in a standard
installation:
| Option (field name) | Default | Meaning |
|---|---|---|
Language Selection for new Visitors ( |
Site Language (0) |
With Browser Settings (1) a first-time visitor is served in the language the browser asks for (the |
Automatic Language Change ( |
Yes |
When a user logs in, or saves their profile, Joomla switches the site to the front end language stored in their account. |
Item Associations ( |
Yes |
Enables the associations tabs in item editors, and the use of associations by the switcher. If it is off, no association can be created or used. |
Add Alternate Meta Tags ( |
Yes |
Adds one |
Add x-default Meta Tag ( |
Yes |
Adds the |
x-default Language ( |
Default frontend language |
Which language the |
Remove URL Language Code ( |
No |
When Yes, the URLs of the default language have no prefix ( |
Cookie Lifetime ( |
Session (0) |
Session keeps the language in the session; Year writes a cookie with a one-year life that remembers the visitor’s choice. |
How the language of a request is decided
The class LanguageFilter is where the diagram at the top of the page comes from. Its router parse rule runs first, and
a second rule, setLanguageApplicationState, decides the language and then detaches itself. The order is:
-
The URL. If the first path segment equals the URL Language Code of a content language, that language is used and the segment is removed from the path before routing continues. If the URL has both a prefix and a
langquery parameter, the parameter wins. -
A request that cannot be redirected. When Remove URL Language Code is on, when the request is a POST (or has posted data or files), or when the query parameter
nolangfilter=1is present, the default content language is used without redirects. This keeps form submissions, uploads and API-like calls working on the language they were rendered in. -
The remembered language. Otherwise the cookie (with Cookie Lifetime set to Year) or the session value is read; it is accepted only if it names a known content language.
-
The browser. If nothing was remembered and Language Selection for new Visitors is Browser Settings, Joomla’s language detection (
LanguageHelper::detectLanguage()) compares the browser’s languages with the content languages. -
The default. Otherwise the default site language is used.
When the path is empty (a visit to https://tallpine.example/) and the prefix is not removed, the plugin issues a redirect
to the URL with the prefix, so / becomes /en/ or /de/. The redirect has the HTTP status 301, but the plugin also
sends Expires, Last-Modified and Cache-Control: no-store headers so that browsers do not cache it: a visitor whose
browser prefers German is sent to /de/ and must not be sent there again after changing the browser language. A reverse
proxy or CDN that caches / regardless of cookies and Accept-Language can defeat this; the home URL should either not
be cached or be cached per language (see Caching and Performance).
The resolved language is stored in the application ($app->set('language', ...)), the request input and a new language
object is loaded, including the language files of system plugins already loaded, so the strings the visitor sees match the
URL language, not the language the application booted with. Finally, the cookie or session value is written.
Automatic language change
With Automatic Language Change on, the plugin listens to the user events (onUserLogin, onUserBeforeSave,
onUserAfterSave). After a login, if the user’s account stores a Frontend Language that is a published content
language, the plugin redirects the user to the same page in that language (using the page’s association when one exists,
else the Home item), and remembers it. A member of the Tallpine club who set German in their profile lands on the German
page after logging in from the English one. Turn it off for sites where the language the visitor chose should never be
overridden by the profile.
Remove URL Language Code
Removing the prefix gives the default language shorter URLs (/trails/alpine), which many site owners prefer for the
language that has most traffic. The costs are:
-
the home page of the default language is
/, and the other language is/de/; the plugin never redirects/to a prefixed URL, which also means the browser language is not detected for new visitors in this mode; -
URLs of the default language that already had the prefix (
/en/trails) are redirected to the unprefixed URL, so switching the option later is a site-wide URL change that must be checked against the redirect plan; -
every other language keeps its prefix, so the sef codes must not collide with a first-level menu alias.
Tallpine keeps the prefix in all languages, because it makes the language visible in the address and avoids the non-detection of the browser language.
The privacy and cookie side
With Cookie Lifetime set to Year, the plugin creates a cookie whose name is a hash derived from the word language,
valid for 365 days, flagged httponly, and flagged secure when HTTPS is forced. The plugin reports this to the Privacy
component as a capability (onPrivacyCollectAdminCapabilities), so it appears in the privacy capabilities report and a
site’s cookie policy must mention it. With the default Session setting no extra cookie is created, because the value is
kept in the session. If a site is subject to consent rules, keeping Session avoids another cookie.
The Language Code plugin
System - Language Code (plg_system_languagecode) answers a narrow problem. A language pack has a fixed tag (for
example de-DE), but the content may be aimed at another locale: the Tallpine site publishes German for Switzerland and
Austria and wants search engines to read it as de-CH or de-AT, without installing and maintaining another language pack.
After the plugin is enabled and saved, its settings page lists one text field per installed language, labelled with the
tag. Writing a code in a field tells the plugin to replace that tag in the generated page. The fields are named with the
lowercase tag (de-de); the plugin applies the mapping in onAfterRender on the response body and only on the front end:
-
the
langandxml:langattributes of the<html>element; -
the
hreflangattribute of<link rel="alternate">elements (including those the Language Filter plugin writes); -
the
contentattribute of<meta itemprop="inLanguage">elements.
System - Language Code (plg_system_languagecode) options
en-GB -> (empty: keep en-GB)
de-DE -> de-AT
The plugin changes the text of the response only. It does not change which language files are loaded, which date and number
formats are used, or the URL prefix. The language of the request is still de-DE, so strings that Joomla localises
(Text::_(), date formats) remain German-Germany. The codes should be valid BCP 47 language tags, because they are
published to search engines; the field filter is cmd, which accepts letters, numbers, hyphen, underscore and dot.
A Home menu item for every language
The routing, the switcher and the Multilingual Status check all rely on the Default Page (Home) item. A multilingual site needs:
-
a menu per language (for example
main-menu-enandmain-menu-de) containing the navigation of that language; -
in each menu a Home item with Language set to that language and Default Page set to Yes;
-
one more Home item with Language set to All. It is the fallback used when a language has no Home item and the item that a single-language site would use. It is usually kept in a menu that no module displays; the Multilingual Status module reports the situation when the All home is published but "useless" because every language has its own;
-
a Menu module per menu, with its Language set to the language of the menu and shown in the same position, so that a visitor sees only the menu of the language in use.
The Tallpine site has this layout:
| Menu | Home item | Language | Default Page |
|---|---|---|---|
|
Home |
English (UK) |
Yes |
|
Startseite |
Deutsch (Deutschland) |
Yes |
|
Home (All) |
All |
Yes (for All) |
The Default Page flag is held per language: marking the German Home item as default does not unmark the English one, because Joomla stores one default per language (and one for All). The star shown in Menus > All Menu Items is then shown on three rows. More about menu items, types and the router rules is in Menus and Menu Items.
Each non-Home item in a menu also has a language. An item set to All shows in both language menus if its menu is assigned to modules of both languages, which is correct for a menu used by both languages but usually wrong for a menu of text links. A menu item has an Associations tab (see the section Associations) that links it to its translation in the other menu.
The router builds URLs from the alias path of the item. Two items in different languages can have the same alias, because
the language prefix keeps them apart: /en/trails and /de/trails is valid, but giving the German item the alias
wanderwege makes the German URL readable for German visitors (/de/wanderwege). Aliases are checked against other items
of the same parent and language.
Language-specific modules and content
Menu modules, custom modules and other modules have a Language field. With the Language Filter plugin on, the module list keeps only modules whose language is the current one or All (see Modules and Positions). The same applies to articles, categories, tags, contacts, banners, news feeds and custom fields: each of them has a Language field, and a list shown to an English visitor only contains English items and items set to All. A trail report written once and left on All is shown in both languages (in German for German visitors, but with an English text).
For Tallpine the rules adopted are:
-
trail reports are articles of the categories Trails > Alpine (English) and Trails > Alpine (DE) (German); each category has a language, so articles of a category must have the same language as the category;
-
the Smart Search index (see Smart Search) is language-aware: the search results shown to a visitor are filtered by the current language;
-
the custom fields of articles (
distance-km,difficulty) use field labels with language constants, or one field group per language when labels must differ, and the language of a field decides in which language of articles it is shown (see Custom Fields and the guide page Fields: Multilingual Sites); -
tags (
family-friendly) are created per language and associated like other items when their names differ.
Details of articles and categories are in Articles and Categories and Tags.
The Language Switcher module
Language Switcher (mod_languages) shows one link per available content language. It is a site module of the usual
kind (see Modules and Positions), created in Content > Site Modules > New >
Language Switcher, and it does nothing unless the Language Filter plugin is enabled.
Options
| Option (field name) | Default | Meaning |
|---|---|---|
Pre-text / Post-text ( |
empty |
Text shown before and after the list. |
Use Dropdown ( |
No |
Show a select list instead of a list of links. |
Use Flags For Dropdown ( |
Yes |
Show the flag image of the active language next to the dropdown. |
Use Image Flags ( |
Yes |
Show flag images as links; with No, show text only. |
Full Language Names ( |
Yes |
Use the Title Native of the content language rather than its URL code; shown when a dropdown or no flags are used. |
Active Language ( |
Yes |
Show the current language in the list as well (marked as active). |
Horizontal Display ( |
Yes |
Place the links in a row rather than in a column. |
Alternative Layout ( |
default |
The module layout; template overrides can supply others (see Template Overrides and Alternative Layouts). |
The module also has the usual fields (position, language All, access, menu assignment). Create a single switcher with the language set to All and the menu assignment to On all pages, in a position that every template style shows. A switcher per language is not required.
Which links appear and where they point
For each content language the module calls the same logic as the plugin’s alternate links. A language appears only when:
-
it is published and its content language access level is among the visitor’s access levels;
-
its language pack is installed (a content language without a front end language pack has no switcher link);
-
a Home menu item exists for it.
The target of each link is chosen in this order, as in LanguageFilter::onAfterDispatch():
-
on the Home page of the current language, the Home page of each other language;
-
on the current language, the current URL;
-
the association of the item being displayed (an article, a category, a contact), supplied by the component;
-
the association of the active menu item;
-
otherwise the language is left out of the
hreflanglist, and the switcher falls back to the Home page of that language.
This is why associations matter: without them the switcher sends a German reader of a trail report to the German home page, and Search Engines see no translation relationship between the pages.
<?xml version="1.0" encoding="UTF-8"?>
<!-- Excerpt of the Language Switcher module parameters as stored in #__modules.params -->
<params>
<dropdown>0</dropdown>
<image>1</image>
<full_name>1</full_name>
<show_active>1</show_active>
<inline>1</inline>
</params>
The module HTML can be changed in a template override. The Cassiopeia template ships a child template mechanism described
in Child Templates and the override screens in
Template Overrides and Alternative Layouts; override
mod_languages/default in cassiopeia_tallpine to replace the flags by plain EN / DE text for accessibility.
Setting up the Tallpine site step by step
The sequence below produces a working English and German site, from an installation in English, and is the one the official guide describes for the manual set-up.
-
Install German. System > Install > Languages, then German (DE).
-
Publish the content languages. System > Manage > Content Languages, create
en-GBandde-DEwith the URL codesenandde, and Status published. Order them. -
Create menus. Menus > Manage > New:
main-menu-enandmain-menu-de. -
Create the Home items. In each menu create a Featured Articles (or Category Blog) item with Default Page set to Yes and its language. Then create the neutral Home item with the language All in a hidden menu.
-
Create menu modules. One per menu, same position, with the matching Language.
-
Create categories. Trails > Alpine in English and Trails > Alpine (DE) in German (or Wanderwege > Alpin), each with a language, then associate them (see the section Associations).
-
Create the Language Switcher module with the language All and a position of the template.
-
Enable the plugins System - Language Filter (and, if needed, System - Language Code) in System > Manage > Plugins.
-
Add the Multilingual Status module to the administrator (see the section The Multilingual Status module) and fix what it reports.
-
Write content. Create the English articles, then add the German versions through the Associations tab.
Joomla also ships Multilingual Sample Data, which builds a menu, a category, an article and a switcher for each published language. The guide warns that fixing the sample data afterwards (ordering, module positions, hybrid versus pure multilingual choices) is as much work as building the set-up by hand, and that sample data must not be installed on a site that already has content.
Adding a third language later
A third language, for example Italian for the Dolomites trails, follows the same seven steps in the guide: install the pack, publish and order the content language, create its menu, add a menu module with the language set, create a category and associate it with the existing ones, create a Home item with Default Page set to Yes and the language, and create the first article (using Save as Copy from an existing article, then changing title, category and language, then associating). A new language is not visible in the switcher until its Home item exists.
Associations
What an association is
An association links items that are translations of each other. The data is kept in the table #__associations, with a
context that names the item type (com_content.item, com_categories.item, com_menus.item, com_contact.item,
com_newsfeeds.item, com_modules.item), the id of the associated item, and a key: all rows of one set of
translations share the same key. An item can have at most one translation per language, and an association is symmetrical,
because every member of the set carries the same key.
-- Which items belong to the translation set of the English article with id 42?
SELECT a.id, a.context, a.`key`, c.language, c.title
FROM #__associations AS a
JOIN #__content AS c ON c.id = a.id
WHERE a.context = 'com_content.item'
AND a.`key` = (
SELECT `key` FROM #__associations
WHERE context = 'com_content.item' AND id = 42
);
The set of items that support associations is:
| Extension | Item types | Association tab in |
|---|---|---|
Articles ( |
Articles and article categories |
Article editor, Category editor |
Contacts ( |
Contacts and contact categories |
Contact editor, Category editor |
News Feeds ( |
News feeds and news feed categories |
Feed editor, Category editor |
Menus ( |
Menu items |
Menu item editor |
Site modules ( |
Module instances |
Module editor |
Third-party components can support associations too. A component declares it with AssociationServiceInterface (the Joomla
4 service model), supplies a helper that returns the translations of the item shown on the page, and registers it in its
service provider; LanguageFilter::onAfterDispatch() calls that helper (getAssociationsForItem()) to build the alternate
links. Components written for Joomla 3 had a ...HelperAssociation class, which the plugin still tries to load for
compatibility.
Tags and custom fields have their own Language but no Associations tab: their translations are separate tags and separate fields, kept tidy by naming. Banners can be given a language but are not associated. The language of a category and the language of its articles must agree, because the filters work per language.
Associating from the item editor
The usual way to translate is from the editor of the item in the reference language:
-
Create the item (an article) in English and set Language to English (UK), choosing a category of the same language.
-
Save, then open the Associations tab. There is one panel per other content language.
-
Press Create next to German. Joomla opens a modal with the form for a new German article, with the Language fixed to German; write the translated title and text, choose the German category and Save & Close.
-
Save & Close the English article.
The tab also offers Select for an existing article and Clear to remove a link. For categories and menu items the workflow is identical, and a menu item association needs the target item to be in a menu of the target language.
An article cannot be associated with itself, with an article of the same language, or with an item with the language All: the language selector of the association modal lists only items of the right language.
Multilingual Associations: the side-by-side editor
Components > Multilingual Associations (com_associations) is a component for translators. It shows the reference
language item and the target language item side by side, so a translator can see the source while writing. The steps are:
-
Open Components > Multilingual Associations.
-
Select the Item Type (Articles, Categories, Menu Items, Contacts, News Feeds, Modules) and the Reference Language (for Tallpine, English). The list shows each item of the reference language and, in a column per other language, its associated item or a Not Associated button.
-
Press the button of a target language (for example
de-DE). The Edit Associations page opens with the reference on the left (read-only) and the target on the right. Write the Target Title and the text, choose the matching category and use Save Target. -
Close returns to the list. Copy Reference to Target copies the reference content to the target, a quick way to start a translation. Show Reference / Hide Reference toggles the left panel.
The component has an Options screen and two maintenance toolbar buttons: Delete All Associations purges the table, and Delete Orphans removes association rows whose item no longer exists. Both are destructive and should be preceded by a database backup.
The component shows an error (You can’t create Multilingual Associations if the site is not set as multilingual and/or Associations is not enabled in the Language Filter plugin) when the plugin is off or Item Associations is No.
<?php
// Reading the translations of an article from template or plugin code.
\defined('_JEXEC') or die;
use Joomla\CMS\Language\Associations;
use Joomla\CMS\Language\Multilanguage;
if (!Multilanguage::isEnabled() || !Associations::isEnabled()) {
return;
}
$articleId = 42;
// Array indexed by language tag; each entry has the id and the language of the translation.
$translations = Associations::getAssociations(
'com_content', // extension
'#__content', // table of the items
'com_content.item', // association context
$articleId // id of the item displayed
);
foreach ($translations as $tag => $item) {
echo $tag . ': article ' . $item->id . "\n";
}
Associations in routing and SEO
When the page shown is an article, the Language Filter plugin asks the component for the article’s associations and uses
them for the hreflang links. If the page has no component associations (a list of articles reached by a menu item), the
associations of the active menu item are used. The x-default link points to the x-default Language option, usually the
default language. A page with a language that has no association is left out of the alternate list, and an alternate list
with one entry is not written at all (the plugin adds links only when at least two languages remain).
<link href="https://tallpine.example/en/trails/alpine/schneeberg" rel="alternate" hreflang="en-GB">
<link href="https://tallpine.example/de/wanderwege/alpin/schneeberg" rel="alternate" hreflang="de-DE">
<link href="https://tallpine.example/en/trails/alpine/schneeberg" rel="alternate" hreflang="x-default">
Pitfalls with associations
-
An association links items of different languages, so an item whose language is changed to the language of its translation, or to All, no longer fits the set. Clear the association first.
-
Associating a menu item does not associate the article it points to; each needs its own association.
-
After Save as Copy check the Associations tab of the copy and re-associate it if the copy is meant as a translation.
-
An item in the trash cannot be displayed. Clear its association before trashing it, otherwise the switcher can point to a page that gives an error.
The Multilingual Status module
Multilingual Status (mod_multilangstatus) is an administrator module intended for the status position of the
administrator template, the bar at the bottom of the screen in Atum. It shows a
button with the title Multilingual Status that opens a modal with two tables, and a warning icon when there is a problem.
The first table gives the status of the global set-up:
-
whether the Language Filter plugin is enabled or disabled;
-
whether a Language Switcher module is published;
-
whether Home pages exist for every content language and the All home status (published, "useless" and so on);
-
the default site language.
The second table lists each content language with its state: published, unpublished or trashed; a missing URL Language Code; a language tag that does not match an installed language; an unpublished Home item; and contacts whose language is inconsistent.
The messages in this module are the first place to look when a language does not appear in the switcher, when the
site redirects in loops, or when a menu is empty in one language. The module uses the model
MultilangstatusModel of com_languages and only reports; it fixes nothing.
Language overrides
What they are
A language file such as language/de-DE/com_content.ini holds the constants and strings of an extension. Because updates
overwrite those files, a site that wants a different wording does not edit them. It stores the replacement in an override
file: language/overrides/de-DE.override.ini for the site and administrator/language/overrides/de-DE.override.ini for
the administrator, one file per language. The lines have the form KEY="Translation".
The order of loading is: the en-GB strings first (so no raw constant appears), then the strings of the active language
(which replace those of en-GB), then the override file, which wins over both. Extensions should keep their own language
files in their own folder and use overrides only for local wording changes.
Editing overrides
-
Open System > Manage > Language Overrides.
-
Select the language and the location (Site or Administrator).
-
Press New. Type the constant to change (the screen has a search box to find constants by their text or name), pick it from the results, enter the new text and Save & Close.
-
Repeat for each language, since the file of one language does not apply to others.
; language/overrides/en-GB.override.ini (site)
COM_CONTENT_READ_MORE_TITLE="Read the full trail report"
MOD_TALLPINE_NEXTHIKES_HEADING="Next hikes"
; language/overrides/de-DE.override.ini (site)
COM_CONTENT_READ_MORE_TITLE="Den ganzen Tourenbericht lesen"
MOD_TALLPINE_NEXTHIKES_HEADING="Naechste Wanderungen"
Points to remember:
-
Site and administrator overrides are separate. A site string overridden in the administrator list does nothing on the front end.
-
A value is a quoted string. A double quote inside the text is written
"_QQ_"; the characters%sand%1$sare placeholders forsprintfand must be kept. -
An override is applied after the extension has loaded its file. Constants that an extension builds dynamically (a constant name made from a variable) cannot be found by the search and need the key typed by hand.
-
Overrides are plain files, so they can be committed to version control, copied between environments, and handled by deployment scripts like any other configuration.
-
With page caching in front of the site, clear the cache after a change (see Caching and Performance).
Debugging a translation
When a string is wrong or untranslated, set Debug Language to Yes in System > Global Configuration > System, and keep
Language display on Value. Translated strings are shown between asterisks, strings that could be translated but whose
constant is not found between question marks, and strings that are not translatable are shown plainly. Enable the plugin
System - Debug and set Debug System to Yes to get a debug panel with the lists of loaded language files and of
untranslated constants. The panel is a development aid and must not be left on in production, because it exposes file
paths and queries. See also Debugging and
Language Files and Internationalisation for the developer
side (constants, Text::_(), plurals and .sys.ini files).
Language fallbacks (Joomla 6.2)
Joomla 6.2 adds language fallbacks for regional variants. A site in German for Switzerland (de-CH) can use the strings of
de-DE for the constants that an extension did not translate into de-CH, rather than showing English. The fallback is
resolved per string, not per file: a string in the regional file always wins, a string missing there is taken from the
fallback language, and a string missing in both falls back to the usual default, en-GB.
A fallback is configured in System > Manage > Languages > Options > Language Fallback, under Fallback Overrides, with a
pair "active language and fallback language" such as de-CH and de-DE. The fallback language should be installed on the
site. A language pack author can also suggest a fallback with an optional element in the pack’s langmetadata.xml; the
administrator’s setting has precedence over it, and the pack’s setting over the standard behaviour. Fallbacks are off until
a pack or an administrator defines one, so existing sites behave as before after updating to 6.2.
Common errors and pitfalls
| Symptom | Cause and fix |
|---|---|
Switching language leads to a Page Not Found error |
The page has no association, and the target menu item is missing or has the wrong language. Create the associations, or make sure the other language has a published Home item. A menu item that points to an article used as a translation source should have its own language set. |
A language does not appear in the switcher |
The content language is unpublished or trashed, its pack is not installed, its access level excludes the visitor, or it has no Home item. The Multilingual Status module lists which. |
The site redirects in a loop, or |
A proxy or CDN caches the 301 from |
German visitors see English text in a German page |
The article has the language All or the language of a different category; the language pack lacks the string (use an override or, since 6.2, a fallback); or the extension has no German file. |
A menu shows items of both languages |
The menu items have the language All, or the menu module has the language All and the menu mixes languages. Use one menu and one module per language. |
Associations are impossible to create |
The Language Filter plugin is disabled, or Item Associations is No, or the item has the language All. |
A form (search, login) switches the language after submitting |
The request is a POST, which uses the default language. Make the form action include the language prefix, and test the forms in each language. |
|
Add Alternate Meta Tags is off, only one language remains available for the page, or the page has no associations. |
URLs of a language changed after editing the content language |
The URL Language Code is part of every URL. Restore it, or add redirects (see SEO, SEF URLs, Redirects and Schema.org). |
Search finds items of the other language |
Smart Search taxonomy or filters are not language-limited; check the language of the indexed items and of the search menu item (see Smart Search). |
Other cautions:
-
Do not enable the Language Filter plugin on an existing single-language site before the structure exists: every item with the language All continues to work, but the first request to
/redirects to a prefixed URL that has no Home item, and the site is an error page until the Home items exist. Build the structure first, enable the plugin last. -
Pick the default language once. The Home item of the default language and the plugin’s fallback use it, and changing it on a live site changes the language of
x-defaultand of every unprefixed URL when Remove URL Language Code is on. -
Cache plugins (Page Cache, Progressive Caching) must be tested in every language: cache keys must include the language, which the core ones do, but third-party caches or CDNs may not.
Security considerations
-
Language is user input. The language prefix, the
langquery parameter, the cookie and theAccept-Languageheader are all supplied by the client. The Language Filter plugin only accepts values that are known content languages and ignores others, so extension code should do the same and never use the raw value to build a file path or an SQL clause. -
Overrides end up in pages. A translated string is printed by the code that uses it, and many strings are output as HTML. Do not accept markup or script from untrusted translators, and grant access to the Language Overrides screen only to trusted users.
-
Language access levels hide unfinished translations. Setting the content language’s Access to a restricted level keeps a translation out of the public switcher and the alternate links while the editors finish it, but a direct URL of a published item with a public access level remains reachable; restrict the items themselves as well.
-
The privacy of the cookie. The one-year language cookie is a functional preference stored in the visitor’s browser; see the section The privacy and cookie side and the Privacy tools in Privacy and Action Logs.
-
Language packs are installable extensions. Install them only from the official list on the Install Languages page.
Version notes and book corrections
-
Joomla 6.2: language fallbacks (System > Manage > Languages > Options > Language Fallback).
-
Joomla 6.1: module associations (Associations tab of site modules) and module versioning (see Modules and Positions).
-
Joomla 6.0: the Language Code plugin class is
final, like other core plugin classes, so a third-party plugin should subscribe to events instead of extending it. The legacy...HelperAssociationloading is kept for components that have not yet moved toAssociationServiceInterface, but new code should implement the service interface. -
Joomla 3.7 and later: the Multilingual Associations component (
com_associations) is part of core. -
Joomla 4 and 3 are end of life, Joomla 5.4 is security-only. New multilingual sites should start on Joomla 6.2; see Upgrading Joomla 5 to 6 for existing ones.
Older books and online tutorials differ in several points:
-
Joomla! 4 Masterclass (2023) targets Joomla 4.x, which reached end of life in October 2025. Its multilingual chapter is correct about the principles (content languages, Home per language, associations, switcher), but screen names and options should be checked against Joomla 6.2, and the links to
docs.joomla.org/J4.xpages and thelaunch.joomla.orgpages it refers to have been replaced by the Joomla User Guide atguide.joomla.org. Joomla 6.2 adds language fallbacks and module associations, which the book cannot mention. -
Developing Extensions for Joomla! 5 (2023) shows
Factory::getLanguage()andFactory::getApplication()->getLanguage()and calls such asText::_()in extension code. In Joomla 6, prefer the application or the dependency injection container to obtain the language object; theJ*aliases (JText,JFactory) are available only with the Behaviour - Backward Compatibility 6 plugin. The multilingual developer side is in Language Files and Internationalisation. -
Tutorials of the Joomla 3 era describe the Language Filter plugin options by their old labels and recommend creating the multilingual structure by hand with the Multilingual Sample Data installer; the labels listed on this page are those of the 6.2 source.
-
The wiki page
docs.joomla.org/Setting_up_your_multilingual_siteand similar pages ondocs.joomla.orgare the legacy documentation and mark themselves obsolete. The current end-user pages are the Languages section of the Joomla User Guide.