single-spa / single-spa-angular

Helpers for building single-spa applications which use Angular
Apache License 2.0
198 stars 78 forks source link

How to handle router links between different single-spa application subrouters #62

Closed liuyiba closed 5 years ago

liuyiba commented 5 years ago

In the coexisting-angular-microfrontends, the navbar works will to switch different apps. In app1 I have two subrouters "/app1/subRouter1" and "app1/subRouter2" In app2 there are also have two subrouters "/app2/subRouter1" and "app2/subRouter2". Now If there is a link on "/app1/subRouter1" page go to app2 subrouter2. That will not work, image How to fix this?

joeldenning commented 5 years ago

Hi @liuyiba, could you please push your code to a github repository for me to debug with?

liuyiba commented 5 years ago

Hi @joeldenning I splite the coexisting-single-spa-angular into two project to test the apps from different domain. And have uploaded it here: https://github.com/liuyiba/Single-spa-angular-cross-domain. You can clone and debug it. Otherwise I also want to know do you have any examples about the communication between different apps from the different domain. In my case: I want to pass the authentication information or some other events from app to app2.

kbjerke commented 5 years ago

@liuyiba I think for the first part of your question you're going about it in the wrong way. ng serve will serve the angular application, while single-spa requires the static built js-bundle from the project. You will need to have a webserver/CDN serve the main.js (default name) from app x and y, and have the single-spa application fetch the bundle at runtime to register applications.

...
  <script src="https://example-x.com/appX/dist/appX/main.js"></script>
  <script src="https://example-y.com/appY/dist/appY/main.js"></script>
  <script>
    singleSpa.registerApplication('appX', window.appX.default, function(location) { return location.pathname.startsWith('/appX'); });
    singleSpa.registerApplication('appY', window.appY.default, function(location) { return location.pathname.startsWith('/appY'); });
    singleSpa.start();
  </script>
...

I initially thought this issue was related to something else, and I did notice @joeldenning that the router was having issues with accessing sub-routes from different apps when the: providers: [{provide: APP_BASE_HREF, useValue: '/appX'}] was removed from the different applications in the coexisting-angular-microfrontends example.

I forked and made some changes to have it working in both IE11 and having sub-routes working again: fork

liuyiba commented 5 years ago

Hi @kbjerke , Both the app and app2 are the single-spa-angular project. And I also got the the main.js before register as single spa application. It works will. And all the navbar routers work will for me. And I run your code, found your code is different from my question.

My subrouters are not on the navbar. It is the subrouters in app and app2. I expect when you under app1/subrouter2 and click here will direct you to the app2/subrouter2. I upload a pic to help understanding my question, and you can also download my code and play. image

joeldenning commented 5 years ago

@liuyiba I will take a look at your github repo when I get a chance and see if i can find the problem.

@kbjerke I appreciate your help fielding some of these questions. You mentioned that you forked coexisting-angular-microfrontends and added back in the APP_BASE_HREF to the router and that it fixed issues with sub routes. But the reason I removed the APP_BASE_HREF is because navigation between two applications failed with the base href, since the application that was about to unmount would freak out that the new url didn't match any of the routes it knew about and so it threw an error (iirc). Could you clarify how subroutes weren't working for you without the APP_BASE_HREF? And maybe we could create a new github issue for it if there's a problem with nested routes.

joeldenning commented 5 years ago

I believe this is related to not having an EmptyRouteComponent as the ** route. Additionally, you need to add the APP_BASE_HREF with useValue /as a provider in app-routing module. See this documentation for how to fix it.

Apologies for the slow response here. If it turns out to be something besides what is described above, feel free to reopen.

pravinparab commented 3 years ago

Hi liuyiba,

have you got any solution for single spa child application routing ? please share with me because i am also facing same issue

reshnaz commented 3 years ago

@liuyiba, I followed the method described in the documentation and it worked for me. For example, below is how I have configured my routes in my routing module. APP_BASE_HREF will be "/": *const routes: Routes = [ { path: 'app1/subroute1', component: Component1, children: [ { path: 'childofsubroute1', component: ChildOfComponent1, }, ] }, { path: 'app1/subroute2', component: Component2, }, { path: '*', component: EmptyRouteComponent } ];

In your HTML, you will have something like this for the first level of sub-routes: <a routerLink="/app1/subroute1">First Component</a> <a routerLink="/app1/subroute1">Second Component</a> For your second level, configure as below: <a routerLink="/app1/subroute1/childofsubroute1">Link to child</a>

Hope this helps!

@joeldenning But I have another problem when re-loading a page that has a second level of routes in the URL. For example, when I refresh a page with a URL such as below, the page loses its styling. http://localhost:4200/app1/subroute1/childofsubroute1 I am using CSS Bootstrap and I have included the required js files in the root/container app's index.html:




Whenever I reload such a page, I see the below errors in console and the page loses its styling. ![image](https://user-images.githubusercontent.com/31286438/96045998-66efc080-0e90-11eb-90c4-fec450ae645e.png) Thereafter, though the routing works, all the pages seem to lose styling. Am I missing something?
reshnaz commented 3 years ago

@liuyiba, I followed the method described in the documentation and it worked for me. For example, below is how I have configured my routes in my routing module. APP_BASE_HREF will be "/": const routes: Routes = [ { path: 'app1/subroute1', component: Component1, children: [ { path: 'childofsubroute1', component: ChildOfComponent1, }, ] }, { path: 'app1/subroute2', component: Component2, }, { path: '**', component: EmptyRouteComponent } ];

In your HTML, you will have something like this for the first level of sub-routes: <a routerLink="/app1/subroute1">First Component</a> <a routerLink="/app1/subroute1">Second Component</a> For your second level, configure as below: <a routerLink="/app1/subroute1/childofsubroute1">Link to child</a>

Hope this helps!

@joeldenning But I have another problem when re-loading a page that has a second level of routes in the URL. For example, when I refresh a page with a URL such as below, the page loses its styling. http://localhost:4200/app1/subroute1/childofsubroute1 I am using CSS Bootstrap and I have included the required js files in the root/container app's index.html:

Whenever I reload such a page, I see the below errors in console and the page loses its styling. image

Thereafter, though the routing works, all the pages seem to lose styling. Am I missing something?

This must have been silly to miss but this issue got fixed by adding <base href="/"> below the title tag in the container index.html :)

bhargavr445 commented 3 years ago

I am working on a project with micro-services architecture, currently I have 3 projects

  1. root-config(This is where I register all my microservices based on the route, microservice will load on to the DOM).
  2. app1(this is in angular, when I see localhost:9000/app1 I am able to load the app, but when I want to do routing with in app1 ie localhost:9000/app1/employee I dont see routing is working)
  3. app2 Could you please help me with this. Thanks
joeldenning commented 3 years ago

Hi @bhargavr445, could you create a separate Github issue with a demonstration of the problem? Also, you can join our single-spa slack workspace which has lots of people who can try to help you figure out the problem.

JMAmimacom commented 2 years ago

Hi all, I have a 'routing' problem.

in the single-spa i load 4 different apps and i have one of them as default routing

      <single-spa-router>
        <nav></nav>
        <main>
          <route default>
            <application name="@myApp/app1"></application>
          </route>
          <route path="/app1">
            <application name="@myApp/app1"></application>
          </route>
          <route path="/app2">
            <application name="@myApp/app2"></application>
          </route>
          <route path="/app3">
            <application name="@myApp/app3"></application>
          </route>
          <route path="/app4">
            <application name="@myApp/app4"></application>
          </route>
        </main>
      </single-spa-router>

Each app is an angular app with its own router.

If i try to navigate between apps, the navigation is perfect, but if i try to navigate in an app to one page that corresponds to the app subrouter, single-spa loads the default route, the only 'internal' navigation that works is the one on the default route (app1)

This only happens when i deploy the single-spa and the apps, if i serve it in local, it works perfectly.

Any help on this!!?