angularangular-router

Angular redirect route to server file


We have an application, and it should be able to display its license file that is part of the build package. Normally, this would be simple enough: a relative link to /3rdpartylicenses.txt will resolve to the file on the server, if no other route is triggered first.

This application, however, is intended for web publication and integration into other websites. So you'd specify the content you want to display right there in the first route variable, for example https://myapp/mycontent.

For this purpose, there's a wildcard in the routing that redirects everything to a component that loads in the specified content:

{path: ':token', component: FeedSelectorComponent}

In other words, any relative URL that is not otherwise explicitly routed ends up here.

So I need to explicitly route /thirdpartylicenses.txt to the file located on the server. Except I have no idea how to express that and can't find the use case in the documentation.

I've tried redirecting to itself, but that seems to end up in the same place (interestingly enough does not cause a recursion, though):

{path: '3rdpartylicenses.txt', redirectTo: '/3rdpartylicenses.txt'},

Presumably there must be some way to express this redirect, but I can't find it.

The file is in its default location when exported by angular during the build process, which is the root folder. This works perfectly fine on another application that we have, but that one doesn't have a wildcard in the routing...


Solution

  • The core issue was not actually route syntax, it was route order. I was aware that the router works on a first-hit-first-served basis, but I failed to realise that it goes in reverse order of definition.

    My routing looked like this:

    const routes: Routes = [
      {path: '', redirectTo: '/not-found/no-token', pathMatch: 'full'},
      {path: '3rdpartylicenses.txt', redirectTo: `/3rdpartylicenses.txt`},
      {path: ':token', component: FeedSelectorComponent},
      {path: 'not-found/:token', component: PageNotFoundComponent},
    ]
    

    The idea being that when a request came to /3rdpartylicenses.txt, it would get hit before the :token wildcard and turn into a server lookup. However, the request ended up at the FeedSelectorComponent anyways, leading me to believe that the router resolved the /3rdpartylicenses.txt path locally without sending it back to the server. That's why I was asking if there was an explicit way to tell it to fall back to the server.

    However, that's exactly the behaviour it would have exhibited with this syntax, if the route had actually been triggered. It was not, because the priority of routes goes in reverse. Once I changed the order, everything actually worked:

    const routes: Routes = [
      {path: '', redirectTo: '/not-found/no-token', pathMatch: 'full'},
      {path: ':token', component: FeedSelectorComponent},
      {path: '3rdpartylicenses.txt', redirectTo: `/3rdpartylicenses.txt`}, // Moved this to appear *after* the :token wildcard, so it gets triggered *before* it.
      {path: 'not-found/:token', component: PageNotFoundComponent},
    ]