https://customer1.com/about -> de
https://customer2.de/en/about -> en
https://customer3.com/fr/about -> fr
Multi-tenancy in i18n refers to serving different localization configurations. This is particularly useful when:
You have multiple customer domains that need different default languages
You're running a SaaS platform where each customer has their own subdomain
Different sections of your app need different localization strategies
For example, you might want:
customer1.fr
to default to French with English as an option
customer2.com
to default to English with French as an option
All other domains to use path-based localization (/en/
, /fr/
)
Multi-tenancy allows you to handle all these cases with a single configuration.
Regional Businesses : Different domains for different markets (e.g., .fr
for France, .de
for Germany)
White-Label Solutions : Each client gets their own domain with specific language preferences
Enterprise Applications : Different departments or subsidiaries need different language defaults
URLPatterns can be used to configure multi-tenancy in your application. Here is an example configuration:
await compile ({
project : "./project.inlang" ,
strategy : ["url" ],
urlPatterns : [
{
pattern : "https://customer1.fr/:path(.*)?" ,
localized : [
["fr" , "https://customer1.fr/:path(.*)?" ],
["en" , "https://customer1.fr/en/:path(.*)?" ],
],
},
{
pattern : "https://customer2.com/:path(.*)?" ,
localized : [
["en" , "https://customer2.com/:path(.*)?" ],
["fr" , "https://customer2.com/fr/:path(.*)?" ],
],
},
{
pattern : "https://:domain(.*)/:path(.*)?" ,
localized : [
["en" , "https://:domain(.*)/en/:path(.*)?" ],
["fr" , "https://:domain(.*)/fr/:path(.*)?" ],
],
},
],
});
Localizing French to French:
localizeHref ("https://customer1.fr/about" , { locale : "fr" })
Localizing from French to English:
localizeHref ("https://customer1.fr/about" , { locale : "en" })
De-localizing English:
deLocalizeHref ("https://customer1.fr/en/about" );
Localizing English to English:
localizeHref ("https://customer2.com/about" , { locale : "en" })
Localizing from English to French:
localizeHref ("https://customer2.com/about" , { locale : "fr" })
De-localizing French:
deLocalizeHref ("https://customer2.com/fr/about" );
For any other domain, the path-based localization will be used for English and French.
localizeHref ("https://example.com/about" , { locale : "fr" })
localizeHref ("https://example.com/fr/about" , { locale : "en" })
In multi-tenant applications, you might need to restrict certain locales for specific tenants. For example:
Customer A only supports English and German
Customer B only supports French and Spanish
Customer C supports all locales
You can implement this by redirecting unsupported locales to a 404 page or any other error page using the null
or 404 redirect pattern:
await compile ({
project : "./project.inlang" ,
strategy : ["url" ],
urlPatterns : [
{
pattern : "https://customer1.com/404" ,
localized : [
["en" , "https://customer1.com/404" ],
["de" , "https://customer1.com/de/404" ],
],
},
{
pattern : "https://customer1.com/:path(.*)?" ,
localized : [
["en" , "https://customer1.com/:path(.*)?" ],
["de" , "https://customer1.com/de/:path(.*)?" ],
["fr" , "https://customer1.com/404" ],
["es" , "https://customer1.com/404" ],
],
},
{
pattern : "https://customer2.com/:path(.*)?" ,
localized : [
["fr" , "https://customer2.com/:path(.*)?" ],
["es" , "https://customer2.com/es/:path(.*)?" ],
["en" , "https://customer2.com/404" ],
["de" , "https://customer2.com/404" ],
],
},
{
pattern : "https://customer3.com/:path(.*)?" ,
localized : [
["en" , "https://customer3.com/:path(.*)?" ],
["de" , "https://customer3.com/de/:path(.*)?" ],
["fr" , "https://customer3.com/fr/:path(.*)?" ],
["es" , "https://customer3.com/es/:path(.*)?" ],
],
},
],
});
When a user tries to access a URL with an unsupported locale for a specific tenant, they will be redirected to the 404 page:
localizeHref ("https://customer1.com/about" , { locale : "fr" })
localizeHref ("https://customer2.com/about" , { locale : "de" })
localizeHref ("https://customer3.com/about" , { locale : "fr" })
This approach allows you to:
Define tenant-specific locale support
Gracefully handle unsupported locale requests
Maintain a consistent user experience across your multi-tenant application
When implementing a language/locale switcher in a multi-tenant application, it's essential to only display the locales that are supported by the current tenant.
This prevents users from clicking on links that would lead to 404 pages or unsupported content.
You should filter the available locales based on the current tenant before rendering your locale switcher:
function getTenantSupportedLocales (hostname ) {
if (hostname.includes ('customer1.com' )) {
return ['en' , 'de' ];
} else if (hostname.includes ('customer2.com' )) {
return ['fr' , 'es' ];
} else if (hostname.includes ('customer3.com' )) {
return ['en' , 'de' , 'fr' , 'es' ];
}
}
function LanguageSwitcher ( ) {
const hostname = window .location .hostname ;
const supportedLocales = getTenantSupportedLocales (hostname);
return (
<div className ="language-switcher" >
{supportedLocales.map(locale => (
<a
key ={locale}
href ={localizeHref(window.location.href, { locale })}
>
{locale.toUpperCase()}
</a >
))}
</div >
);
}