简体   繁体   中英

Angular 2 routes - redirect to different app

I'm generating various versions of my app in alternate languages. I'm using AOT (ahead of time) compilations, so I end up with static deployable sites in a structure that looks like this:

dist -
  index.html -- entry file for the default (English language) app
  -fr
    index.html -- entry file for French language version
  -de
    index.html -- entry file for German language version

I can currently switch between the main language websites using a dropdown where the user can select their preferred language, and I then load the main entry file for the required site using plain JavaScript like this:

const baseUrl = window.location.origin;
window.location.href = baseUrl + '/' + requestedLanguage + '/index.html'; // e.g. requestedLanguage = 'fr'

This works, as it seems that requesting the actual index.html file means Angular won't interpret the request href as an Angular route.

What I want to happen though is that when the user enters a URL that already contains the language version in the path, I want that language version to be served. I also want the URL path preserved so that the Angular routing loads the appropriate component for the requested URL.

For example:

  • user enters myDomain.com/fr/myPage

  • the app under the /fr/ subdirectory is loaded, and the Angular routing in that app loads the related component for MyPage

Currently if I enter a URL myDomain.com/fr/myPage , the Angular routing tries to interpret the desired subfolder fr as a route, which doesn't exist, so I get the following error:

Error: Cannot match any routes. URL Segment: 'fr/instruments'

How can I load the required app and the correct component? There must be a way of getting Angular to recognise that the fr in the URL refers to a different app. Maybe I'm missing a build configuration or something? Here's my script in package.json for building the French language version:

"build:fr": "ng build --aot --output-path=dist/fr --base-href /fr/ --i18nFile=src/locale/messages.fr.xlf --i18nFormat=xlf --locale=fr",

just use Components instead of different separate apps and use below example >

{path:'',component:EnHomeComponent},
  {path:'contact',component:EnContactComponent},
  {path:'fr',component:LayoutComponent,
   children:[
     {path:'',component:FrHomeComponent},
     {path:'contact',component:FrContactComponent}]} 

then you can directly access the pages by URL

Use angular router concept for different paths of English, France and Danish.

Then use the path based on language.

I was able to load differing language versions of the app by configuring the pipeline for my .NET back end like this, so that the Angular static index page is loaded for each different language app (referred to as 'SPA' in the code). It works by checking if there is an 'index.html' page for the first subfolder in the request URL (eg '/fr/', '/de/'), and it loads that page if it exists:

Startup.cs

public class Startup
{
    public void Configuration()
    {
        app.Use((context, next) =>
        {
            if (!context.Request.Path.HasValue)
                return next();

            IFileInfo fi;
            string spaIndex = "index.html";

            Uri uri = new Uri(context.Request.Uri.ToString());
            var segs = uri.Segments;
            var folder = segs.Length > 1 ? String.Format("/{0}", segs[1]) : "/";

            if (!physicalFileSystem.TryGetFileInfo(context.Request.Path.Value, out fi)) {

                // check if this is a request for a sub-application, e.g an alternative language version
                // if so, load the app
                if (physicalFileSystem.TryGetFileInfo(String.Format("{0}{1}", folder, spaIndex), out fi))
                {
                    context.Request.Path = new PathString(String.Format("{0}{1}", folder, spaIndex));                           
                }
            }

            return next();
        });
    }
}

The remainder of the URL (the part after the language subfolder) is then interpreted as a route inside the app that has been loaded (eg the French language app). This means that the correct component is loaded for the app (I'm not entirely sure how this part is working - maybe the remainder of the path falls through to a different part of the .NET request pipeline and is passed onto the Angular app?)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM