web-dev-qa-db-fra.com

Configuration Nginx pour application i18n angulaire

J'ai construit une application angular-5 utilisant i18n qui prend en charge le français et l'anglais. J'ai ensuite déployé une version distincte de l'application pour chaque langue prise en charge.

 - dist 
 | ___ en /
 | | __ index.html 
 | ___ fr /
 | __ index.html 
 

J'ai également ajouté la configuration nginx suivante pour servir l'application dans les deux langues.

 serveur {
 racine /var/www/dist;
 index index.html index.htm; 
 nom_serveur Host.local; 
 
 location ^/(fr | en)/(. *) $ {
 try_files $ 2 $ 2//$1/index.html;
} 
} 

Ce que je voulais faire, c'est servir les deux applications et permettre de basculer entre la version anglaise et la version française.

Disons par exemple que je suis sur Host.local/en/something Si je passe à Host.local/fr/something je devrais obtenir la version française de la page "quelque chose".

Avec la configuration nginx que j'ai partagée, une erreur 404 non trouvée se produit chaque fois que j'actualise les pages lors du brassage de mes applications, ce qui m'empêche également de parcourir mes applications indépendamment les unes des autres et de basculer entre elles.

Qu'est-ce que j'ai raté? Quelle est la config Nginx appropriée pour y parvenir?

7
Ahmed Siouani

j'ai fait la même chose sur IIS, vous devez d'abord créer votre application avec l'option "base-href":

 ng build --output-path=dist/fr --prod --bh /fr/
 ng build --output-path=dist/en --prod --bh /en/

et pour nginx utiliser cette config 

location /fr/ {
  alias /var/www/dist/fr/;
  try_files $uri$args $uri$args/ /fr/index.html;
}
location /en/ {
 alias /var/www/dist/en/;
 try_files $uri$args $uri$args/ /en/index.html;
}

et pour la navigation de/en/someroute à/fr/someroute, vous pouvez obtenir l'URL du routeur actuel dans votre composant où vous avez le sélecteur de langue. 

getCurrentRoute() {
    return this.router.url;
}

et lorsque vous cliquez sur un sélecteur de langue, vous redirigez le même itinéraire avec la langue sélectionnée:

 <li *ngFor="let language of languages;let i=index" >
    <a  href="/{{language.lang}}/#{{getCurrentRoute()}}"  (click)="changeLanguage(language.lang)">
        {{language.lang}}
    </a>
 </li>

changer de langue

changeLanguage(lang: string) {
    const langs = ['en', 'fr'];
    this.languages = this.allLanguages.filter((language) => {
        return language.lang !== lang;
    });
    this.curentLanguage = this.allLanguages[langs.indexOf(lang)].name
    localStorage.setItem('Language', lang);
    if (isDevMode()) {
        location.reload(true);
    }
}
5
Fateh Mohamed

Après avoir construit avec:

ng build --prod --base-href /fr/ --output-path dist/fr
ng build --prod --base-href /en/ --output-path dist/en

copiez les versions dans le répertoire de services nginx:

cp -r dist/* /usr/share/nginx/my-app

Ensuite, j'ai trouvé 2 configurations différentes de NGINX qui fonctionnent pour moi:

Utiliser le chemin racine

server {
    root /usr/share/nginx/my-app;
    location /en/ {
        autoindex on;
        try_files $uri$args $uri$args/ /en/index.html;
    }

    location /fr/ {
        autoindex on;
        try_files $uri$args $uri$args/ /fr/index.html;
    }

    # Default to FR
    location / {
        # Autoindex is disabled here + the $uri$args/ is missing from try_files
        try_files $uri$args /fr/index.html;
    }
}

Utiliser un alias

server {
    listen 80 default_server;
    index index.html;

    location /en/ {
        alias /usr/share/nginx/my-app/en/;
        try_files $uri$args $uri$args/ /en/index.html;
    }

    location /fr/ {
        alias /usr/share/nginx/my-app/fr/;
        try_files $uri$args $uri$args/ /fr/index.html;
    }

    # Default to FR
    location / {
        alias /usr/share/nginx/my-app/fr/;
        try_files $uri$args $uri$args/ /fr/index.html;
    }
}

Note : Dans le chemin racine solution, vous pouvez supprimer l’option autoindex on mais vous devrez également supprimer la partie $uri$args/ du try_files sinon vous obtiendrez " index de "[répertoire]" est une erreur interdite ".

FYI: Vous pouvez trouver utile ces explications intéressantes sur ROOT vs ALIAS .

Les versions

Angular CLI: 6.0.7
Node: 8.11.2
Angular: 6.0.3
4
nyxz

Il existe un malentendu courant dans la manière dont http://nginx.org/r/try_files fonctionne. Si vous regardez de plus près dans la documentation (à partir du lien ci-dessus), vous remarquerez que, bien que les paramètres premiers et intermédiaires de la directive try_files soient de type "fichier", le dernier est appelé "uri"; qui, dans votre cas, une fois que vous corrigez votre http://nginx.org/r/location pour gérer l’expression rationnelle de manière appropriée (votre code location ne contient pas le modificateur ~), peut entraîner une boucle infinie, confirmez dans vos commentaires.

Notez qu'en général, il n'est pas recommandé d'utiliser les expressions régulières dans nginx pour des performances optimales dans les situations simples où l'utilisation de regex pourrait également être évitée. Nous vous recommandons donc de disposer de deux emplacements indépendants, l'un pour l'anglais et le français.

location /fr/ {
    try_files $uri /fr/index.html =410;
}
location /en/ {
    try_files $uri /en/index.html =410;
}

Notez que le code ci-dessus suppose que vous effectuez une gestion correcte des URL à partir de votre interface Web. Si une ressource donnée est partagée entre les versions /en/ et /fr/, elle sera demandée directement via la base /, sans spécificateur /en/ ou /fr/. La partie =410 du code se comporte de la même manière que le ferait =404, sauf que l'erreur est légèrement différente pour faciliter le débogage de la directive responsable de l'erreur.

0
cnst