I am in the process of internationalizing an Angular 11 application. Things work fine with ng serve
but I am facing issues when deploying, as I can't manage to address the following:
/assets/picture.png
are loaded properly (i.e. transformed in /xx/assets/picture.png
where xx
is the language such as en
or fr
): they trigger a 404 error.https://example.com/records/12
does not trigger an error, and is automatically converted to https://example.com/xx/records/12
(where again, xx
is the language such as en
or fr
).The angular.json
file contains the standard stuff:
"i18n": {
"sourceLocale": "fr",
"locales": {
"en": {
"translation": "src/locale/messages.en.xlf"
}
}
}
...
"localize": true
...
The application is built in 2 languages with ng build --prod --localize
, which generates 2 en
and fr
subfolders within dist
, which I then deploy to the root of the server, next to the following .htaccess
file:
RewriteEngine on
RewriteBase /
RewriteRule ^../index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (..) $1/index.html [L]
RewriteCond %{HTTP:Accept-Language} ^en [NC]
RewriteRule ^$ /en/ [R]
RewriteCond %{HTTP:Accept-Language} !^en [NC]
RewriteRule ^$ /fr/ [R]
(Please note that fr
is the source and default locale, and en
is a translation)
I imagine that the issue comes from the .htaccess
file, because nothing there specifies that https://example.com/assets/picture.png
should transform to https://example.com/en/assets/picture.png
, and likewise for URLs for Angular routes.
Could you please tell me how to fix this?
Note: by viewing the source code of the resulting web page, I could verify that it contains the proper href, e.g. for fr
:
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>MyApp</title>
<base href="/fr/">
It looks like the following works:
RewriteEngine on
RewriteBase /
# keep index.html unchanged
RewriteRule ^(en|fr)/index\.html$ - [L]
# if the URL has no locale prefix, add it (for French)
RewriteCond %{HTTP:Accept-Language} ^fr [NC]
RewriteRule ^(?!(fr|en))(.*)$ fr/$2 [L,DPI]
# same for English
RewriteCond %{HTTP:Accept-Language} ^en [NC]
RewriteRule ^(?!(fr|en))(.*)$ en/$2 [L,DPI]
# at this stage, the URL has a locale prefix
# If the requested resource is not a file/directory, then submit it
# to Angular as a potential route starting with locale
# => redirect to index.html prefixed with the first 2 letters (= locale)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(..).*$ $1/index.html [L]