skip to Main Content

I’m doing an i18n Angular app, so far it works great.

However I have same route strings for different languages, which isn’t best for SEO.

Is it possible to have ‘path’ properties of Routes array be different for each language?

Ex:

const appRoutesEN: Routes = [
  { path: 'crisis-center', component: CrisisListComponent },
  { path: 'hero/:id',      component: HeroDetailComponent },
  {
    path: 'heroes',
    component: HeroListComponent,
    data: { title: 'Heroes List' }
  },
  { path: '**', component: PageNotFoundComponent }
];

Is it possible to define also a appRoutesFR: Routes if yes how I can use it? Shall I inject LOCALE_ID to routing module? If so how?

3

Answers


  1. Chosen as BEST ANSWER

    For the moment there seems to be no easy solution for this. I'll update if I find one.

    Angular i18n people are working to integrate code level internationalization, maybe then.

    Best solution I can come up with is to change routing module(s) in your code and routerLink attributes in templates and all links in other parts of your code for each language, then build your app for each language separately.

    Not ideal at all.

    UPDATE

    As recommended by @estus, I've tried out Greentube/localize-router.

    I wasn't happy to install dependencies like @ngx-translate/core and @ngx-translate/http-loader since I'm using Angular i18n implementation/tools and not ngx-translate.

    It works till it hits a lazy-loaded module with child routes.

    So if you don't have any lazy loaded module with children, localize-router is the way to go.

    UPDATE

    Lazy loaded modules are now supported in the latest version of localize-router.

    Angular i18n will be supported once the programatic translations arrive.


  2. If you need different routing per language as you describe in your comment you could have a dedicated routing module for each individual language. Then define in the angular-cli.json for each language a dedicated app with it’s own main.ts and it’s own AppModule, pulling in only the routing module required for the particular language.

      "apps": [
       {
          "root": "src",
          "name": "yourapp_FR",
    ...
          "main": "./app/yourapp_FR/main.ts",
    ...   
        },
       {
          "root": "src",
          "name": "yourapp_DE",
    ...
          "main": "./app/yourapp_DE/main.ts",
    ...   
        }
        ]
    

    You then build for each language the app like this:

    ng build --app yourapp_FR --i18n-file src/i18n/messages.fr.xlf --locale fr --i18n-format xlf --aot
    

    This way you set it up once and can build each time without commenting out anything.
    I do not have the full context. You say having routes per language is better for SEO. I do not understand this, but if you say so, OK. However I would not like dedicated routing for each language. This means a lot of redundancy and more maintenance.

    Login or Signup to reply.
  3. If you are already using something like @ngx-translate/core then you can create your own mapping instead of adding more external libraries.

    Example:

    function generateI18nRoutes(
        elements: Array<{ i18nPaths: string[]; component: any; data: object; canActivate?: 
    [] }>
    ): Routes {
        return elements.reduce(
            (accumulator, currentValue) => [
                ...accumulator,
                ...currentValue.i18nPaths.map((path: string) => ({
                    path,
                    component: currentValue.component,
                    data: currentValue.data,
                    canActivate: currentValue.canActivate
                }))
            ],
            []
        );
    }
    

    And then use it like:

    const routes: Routes = [
        {
            path: "admin",
            component: AdminLayoutComponent,
            canActivate: [AdminAuthGuard],
            children: generateI18nRoutes([{ i18nPaths: [""], component: HomeComponent, data: { title: "ADMIN" } }])
        },
        {
            path: "",
            component: GeneralLayoutComponent,
            children: generateI18nRoutes([
                { i18nPaths: [""], component: HomeComponent, data: { title: "HOME" } },
                {
                    i18nPaths: ["sign-in", "iniciar-sesión", "iniciar-sessão"],
                    component: SignInComponent,
                    data: { title: "SIGN_IN" }
                }
            ])
        },
        {
            path: "**",
            component: PageNotFoundComponent,
            data: { title: "PAGE_NOT_FOUND" }
        }
    ];
    
    @NgModule({
        imports: [RouterModule.forRoot(routes)],
        exports: [RouterModule]
    })
    export class AppRoutingModule {}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search