I’m working on an Angular project that it is a web app with a landing page. The project is configured to show the landing when the base URL is hit, and to redirect to a login page when trying to access the app with no valid token in session.
The app is contained in its own module that does all the inner routing.
Everything works fine in this two scenarios:
ng serve
ng build
npx lite-server --baseDir="dist/frontend"
Then when building with production flag, routing breaks. These two following ways behave the same:
ng build --prod
npx lite-server --baseDir="dist/frontend"
ng build --prod
firebase deploy
When I try to reach anything inside the "client" module (http://host/client/anything), the app redirects me to the landing again (http://host/landing), no matter how, if pasting the URL in the browser bar or accessing through a control in the landing.
I've read Angular doc for deployment, but tips mentioned there are already configured in my case. Reading other similar stack post over there I could not find a solution.
What I tried so far:
- using hash in routes:
imports: [RouterModule.forRoot(routes, { useHash: true })]
- disabling build optimizer and aot:
ng build --prod --build-optimizer=false --aot=false
- cheking the server config.
index.html
fallback is ok
Enabling tracing let me see that the router is in deed trying to reach the login page, but something that I don't get, breaks in the middle. Production build trace is:
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Ee main-es2015.4665a3d5fdcea262528d.js:1 NavigationStart(id: 5, url: '/client') main-es2015.4665a3d5fdcea262528d.js:1 Ee {id: 5, url: "/client", navigationTrigger: "imperative", restoredState: null}id: 5navigationTrigger: "imperative"restoredState: nullurl: "/client"__proto__: we main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Re main-es2015.4665a3d5fdcea262528d.js:1 RoutesRecognized(id: 5, url: '/client', urlAfterRedirects: '/client', state: Route(url:'', path:'') { Route(url:'client', path:'client') { Route(url:'', path:'') } } ) main-es2015.4665a3d5fdcea262528d.js:1 Re {id: 5, url: "/client", urlAfterRedirects: "/client", state: At} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Oe main-es2015.4665a3d5fdcea262528d.js:1 GuardsCheckStart(id: 5, url: '/client', urlAfterRedirects: '/client', state: Route(url:'', path:'') { Route(url:'client', path:'client') { Route(url:'', path:'') } } ) main-es2015.4665a3d5fdcea262528d.js:1 Oe {id: 5, url: "/client", urlAfterRedirects: "/client", state: At} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: xe main-es2015.4665a3d5fdcea262528d.js:1 ChildActivationStart(path: '') main-es2015.4665a3d5fdcea262528d.js:1 xe {snapshot: Tt} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Fe main-es2015.4665a3d5fdcea262528d.js:1 ActivationStart(path: 'client') main-es2015.4665a3d5fdcea262528d.js:1 Fe {snapshot: Tt} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: _e main-es2015.4665a3d5fdcea262528d.js:1 NavigationCancel(id: 5, url: '/client') main-es2015.4665a3d5fdcea262528d.js:1 _e {id: 5, url: "/client", reason: "Navigation ID 5 is not equal to the current navigation id 6"} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Ee main-es2015.4665a3d5fdcea262528d.js:1 NavigationStart(id: 6, url: '/login?returnUrl=%2Fclient') main-es2015.4665a3d5fdcea262528d.js:1 Ee {id: 6, url: "/login?returnUrl=%2Fclient", navigationTrigger: "imperative", restoredState: null} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Re main-es2015.4665a3d5fdcea262528d.js:1 RoutesRecognized(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'') { Route(url:'login', path:'login') } ) main-es2015.4665a3d5fdcea262528d.js:1 Re {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: At} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Oe main-es2015.4665a3d5fdcea262528d.js:1 GuardsCheckStart(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'') { Route(url:'login', path:'login') } ) main-es2015.4665a3d5fdcea262528d.js:1 Oe {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: At} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: xe main-es2015.4665a3d5fdcea262528d.js:1 ChildActivationStart(path: '') main-es2015.4665a3d5fdcea262528d.js:1 xe {snapshot: Tt} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Fe main-es2015.4665a3d5fdcea262528d.js:1 ActivationStart(path: 'login') main-es2015.4665a3d5fdcea262528d.js:1 Fe {snapshot: Tt} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: De main-es2015.4665a3d5fdcea262528d.js:1 GuardsCheckEnd(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'') { Route(url:'login', path:'login') } , shouldActivate: true) main-es2015.4665a3d5fdcea262528d.js:1 De {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: At, shouldActivate: true} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Pe main-es2015.4665a3d5fdcea262528d.js:1 ResolveStart(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'') { Route(url:'login', path:'login') } ) main-es2015.4665a3d5fdcea262528d.js:1 Pe {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: At} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Te main-es2015.4665a3d5fdcea262528d.js:1 ResolveEnd(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'') { Route(url:'login', path:'login') } ) main-es2015.4665a3d5fdcea262528d.js:1 Te {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: At} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: _e main-es2015.4665a3d5fdcea262528d.js:1 NavigationCancel(id: 6, url: '/login?returnUrl=%2Fclient') main-es2015.4665a3d5fdcea262528d.js:1 _e {id: 6, url: "/login?returnUrl=%2Fclient", reason: "Navigation ID 6 is not equal to the current navigation id 7"} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Ee main-es2015.4665a3d5fdcea262528d.js:1 NavigationStart(id: 7, url: '/') main-es2015.4665a3d5fdcea262528d.js:1 Ee {id: 7, url: "/", navigationTrigger: "imperative", restoredState: null} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Me main-es2015.4665a3d5fdcea262528d.js:1 ActivationEnd(path: 'login') main-es2015.4665a3d5fdcea262528d.js:1 Me {snapshot: Tt} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Ne main-es2015.4665a3d5fdcea262528d.js:1 ChildActivationEnd(path: '') main-es2015.4665a3d5fdcea262528d.js:1 Ne {snapshot: Tt} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Re main-es2015.4665a3d5fdcea262528d.js:1 RoutesRecognized(id: 7, url: '/', urlAfterRedirects: '/landing', state: Route(url:'', path:'') { Route(url:'landing', path:'landing') } ) main-es2015.4665a3d5fdcea262528d.js:1 Re {id: 7, url: "/", urlAfterRedirects: "/landing", state: At} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Oe main-es2015.4665a3d5fdcea262528d.js:1 GuardsCheckStart(id: 7, url: '/', urlAfterRedirects: '/landing', state: Route(url:'', path:'') { Route(url:'landing', path:'landing') } ) main-es2015.4665a3d5fdcea262528d.js:1 Oe {id: 7, url: "/", urlAfterRedirects: "/landing", state: At} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: xe main-es2015.4665a3d5fdcea262528d.js:1 ChildActivationStart(path: '') main-es2015.4665a3d5fdcea262528d.js:1 xe {snapshot: Tt} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Fe main-es2015.4665a3d5fdcea262528d.js:1 ActivationStart(path: 'landing') main-es2015.4665a3d5fdcea262528d.js:1 Fe {snapshot: Tt} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: De main-es2015.4665a3d5fdcea262528d.js:1 GuardsCheckEnd(id: 7, url: '/', urlAfterRedirects: '/landing', state: Route(url:'', path:'') { Route(url:'landing', path:'landing') } , shouldActivate: true) main-es2015.4665a3d5fdcea262528d.js:1 De {id: 7, url: "/", urlAfterRedirects: "/landing", state: At, shouldActivate: true} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Pe main-es2015.4665a3d5fdcea262528d.js:1 ResolveStart(id: 7, url: '/', urlAfterRedirects: '/landing', state: Route(url:'', path:'') { Route(url:'landing', path:'landing') } ) main-es2015.4665a3d5fdcea262528d.js:1 Pe {id: 7, url: "/", urlAfterRedirects: "/landing", state: At} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Te main-es2015.4665a3d5fdcea262528d.js:1 ResolveEnd(id: 7, url: '/', urlAfterRedirects: '/landing', state: Route(url:'', path:'') { Route(url:'landing', path:'landing') } ) main-es2015.4665a3d5fdcea262528d.js:1 Te {id: 7, url: "/", urlAfterRedirects: "/landing", state: At} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Me main-es2015.4665a3d5fdcea262528d.js:1 ActivationEnd(path: 'landing') main-es2015.4665a3d5fdcea262528d.js:1 Me {snapshot: Tt} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Ne main-es2015.4665a3d5fdcea262528d.js:1 ChildActivationEnd(path: '') main-es2015.4665a3d5fdcea262528d.js:1 Ne {snapshot: Tt} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: be main-es2015.4665a3d5fdcea262528d.js:1 NavigationEnd(id: 7, url: '/', urlAfterRedirects: '/landing') main-es2015.4665a3d5fdcea262528d.js:1 be {id: 7, url: "/", urlAfterRedirects: "/landing"} main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Le main-es2015.4665a3d5fdcea262528d.js:1 Scroll(anchor: 'null', position: 'null') main-es2015.4665a3d5fdcea262528d.js:1 Le {routerEvent: be, position: null, anchor: null}
Navigation is cancelled twice. The first should be because of the auth-guard that returns false when trying to get the "client" module, but the reason seems to be another one according to what is logged.
The dev build trace is quite different:
platform-browser.js:96 Router Event: NavigationStart platform-browser.js:87 NavigationStart(id: 5, url: '/client') platform-browser.js:87 NavigationStart {id: 5, url: "/client", navigationTrigger: "imperative", restoredState: null} Router Event: RoutesRecognized RoutesRecognized(id: 5, url: '/client', urlAfterRedirects: '/client', state: Route(url:'', path:'') { Route(url:'client', path:'client') { Route(url:'', path:'') } } ) RoutesRecognized {id: 5, url: "/client", urlAfterRedirects: "/client", state: RouterStateSnapshot} Router Event: GuardsCheckStart GuardsCheckStart(id: 5, url: '/client', urlAfterRedirects: '/client', state: Route(url:'', path:'') { Route(url:'client', path:'client') { Route(url:'', path:'') } } ) GuardsCheckStart {id: 5, url: "/client", urlAfterRedirects: "/client", state: RouterStateSnapshot} Router Event: ChildActivationStart ChildActivationStart(path: '') ChildActivationStart {snapshot: ActivatedRouteSnapshot} Router Event: ActivationStart ActivationStart(path: 'client') ActivationStart {snapshot: ActivatedRouteSnapshot} Router Event: NavigationCancel NavigationCancel(id: 5, url: '/client') NavigationCancel {id: 5, url: "/client", reason: "Navigation ID 5 is not equal to the current navigation id 6"} Router Event: NavigationStart NavigationStart(id: 6, url: '/login?returnUrl=%2Fclient') NavigationStart {id: 6, url: "/login?returnUrl=%2Fclient", navigationTrigger: "imperative", restoredState: null} Router Event: RoutesRecognized RoutesRecognized(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'') { Route(url:'login', path:'login') } ) RoutesRecognized {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: RouterStateSnapshot} Router Event: GuardsCheckStart GuardsCheckStart(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'') { Route(url:'login', path:'login') } ) GuardsCheckStart {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: RouterStateSnapshot} Router Event: ChildActivationStart platform-browser.js:87 ChildActivationStart(path: '') platform-browser.js:87 ChildActivationStart {snapshot: ActivatedRouteSnapshot} platform-browser.js:96 Router Event: ActivationStart platform-browser.js:87 ActivationStart(path: 'login') platform-browser.js:87 ActivationStart {snapshot: ActivatedRouteSnapshot} platform-browser.js:96 Router Event: GuardsCheckEnd platform-browser.js:87 GuardsCheckEnd(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'') { Route(url:'login', path:'login') } , shouldActivate: true) platform-browser.js:87 GuardsCheckEnd {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: RouterStateSnapshot, shouldActivate: true} platform-browser.js:96 Router Event: ResolveStart platform-browser.js:87 ResolveStart(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'') { Route(url:'login', path:'login') } ) platform-browser.js:87 ResolveStart {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: RouterStateSnapshot} platform-browser.js:96 Router Event: ResolveEnd platform-browser.js:87 ResolveEnd(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'') { Route(url:'login', path:'login') } ) platform-browser.js:87 ResolveEnd {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: RouterStateSnapshot} platform-browser.js:96 Router Event: ActivationEnd platform-browser.js:87 ActivationEnd(path: 'login') platform-browser.js:87 ActivationEnd {snapshot: ActivatedRouteSnapshot} platform-browser.js:96 Router Event: ChildActivationEnd platform-browser.js:87 ChildActivationEnd(path: '') platform-browser.js:87 ChildActivationEnd {snapshot: ActivatedRouteSnapshot} platform-browser.js:96 Router Event: NavigationEnd platform-browser.js:87 NavigationEnd(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient') platform-browser.js:87 NavigationEnd {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient"} platform-browser.js:96 Router Event: Scroll
Any help is appreciated. Thanks in advance.