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:
- make sure that assets referred from the code as
/assets/picture.png
are loaded properly (i.e. transformed in/xx/assets/picture.png
wherexx
is the language such asen
orfr
): they trigger a 404 error. - make sure that a URL such as
https://example.com/records/12
does not trigger an error, and is automatically converted tohttps://example.com/xx/records/12
(where again,xx
is the language such asen
orfr
).
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/">
CodePudding user response:
Please check this out, it will help you gain some idea.
custom-link.pipe.ts
@Pipe({
name: "toLangHref",
})
// *To Tranform all Links to multiple Languages Links
export class CustomLinkPipe implements PipeTransform {
constructor(private domSanitizer: DomSanitizer, private router: Router) {}
transform(value: any, args?: any): any {
return this.domSanitizer.bypassSecurityTrustHtml(this.tranformHref(value));
}
tranformHref(innerHtml: string): string {
const langCode = this.getLangCode(this.router.url);
return innerHtml?.replace(/href='/g, `href='/${langCode}`) || innerHtml;
}
getLangCode(path: string): string {
path =
path?.charAt(0) === "/" &&
(path?.charAt(3) === "/" ||
path?.charAt(3) === "?" ||
path?.charAt(3) === "")
? path?.substring(1, 3)
: "";
return path;
}
}
How I use it
"api_section_sub_info_en": "Take your parcel shipping to the next level with our market-leading <a href='/tracking-api'>Tracking API</a> and <a href='/tracking-webhook'>Tracking Webhook</a> solutions, which deliver true end-to-end location and status events in real-time.",
"api_section_sub_info_fr": "Faites passer l'expédition de vos colis au niveau supérieur avec nos solutions <a href='/tracking-api'>API</a> de <a href='/tracking-webhook'>suivi et Webhook de suivi leaders du</a> marché, qui fournissent de véritables événements de localisation et de statut de bout en bout en temps réel.",
<p
[innerHtml]="lang?.api_section_sub_info | toLangHref"
></p>
In my case, I need to translate the whole paragraph with 25 languages, even link's label can be translated. you can use this method to implement for your image :D. Good luck!
hint:
return innerHtml?.replace(/src='/g, `src='/${langCode}`) || innerHtml;
CodePudding user response:
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]