Home > Mobile >  How to redirect assets and page URLs for i18n angular application
How to redirect assets and page URLs for i18n angular application

Time:03-09

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 where xx is the language such as en or fr): 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 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/">

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>

Here is the result

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]
  • Related