How to get Angular routing working when hosting on Azure blob storage
Asked Answered
L

1

6

I have created an Angular application which uses lazy loading and the standard angular routing set up and this set up works well when I run the application locally. But when I try to serve it from azure blob storage I get a 404 when I navigate around the application.

Azure storage static site is enabled and when I navigate to the root page, it is displayed.

What Azure configurations do I need to implement to resolve this issue?

Please note: In an attempt to keep this question concise as possible I have added my attempts below the code. Also I was not sure which Azure configs would be suitable to add so I have left them out until requested.

app-routing.module.ts

    import { NgModule } from '@angular/core';
    import { RouterModule, Routes } from '@angular/router';
    
    const routes: Routes = [
      { path: '', loadChildren: () => import('./feature-modules/home/home.module').then(h => h.HomeModule) },
      { path: 'roadmap', loadChildren: () => import('./feature-modules/roadmap/roadmap.module').then(h => h.RoadmapModule) },
      { path: 'games', loadChildren: () => import('./feature-modules/games/games.module').then(h => h.GamesModule) },
      { path: 'locations', loadChildren: () => import('./feature-modules/locations/locations.module').then(h => h.LocationsModule) },
      { path: 'tasks', loadChildren: () => import('./feature-modules/site-tasks/site-tasks.module').then(h => h.SiteTasksModule) },
      { path: 'contact', loadChildren: () => import('./feature-modules/contact/contact.module').then(h => h.ContactModule) },
      { path: '**', loadChildren: () => import('./feature-modules/not-found/not-found.module').then(h => h.NotFoundModule) },
    ];
    
    @NgModule({
      imports: [
        RouterModule.forRoot(routes)
      ],
      exports: [RouterModule]
    })
    export class AppRoutingModule { }

Roadmap-routing.module.ts

    import { NgModule } from '@angular/core';
    import { RouterModule, Routes } from '@angular/router';
    import { RoadmapComponent } from './roadmap/roadmap.component';
    
    const routes: Routes = [
      { path: '', component: RoadmapComponent }
    ];
    
    @NgModule({
      imports: [RouterModule.forChild(routes)],
      exports: [RouterModule]
    })
    export class RoadmapRoutingModule { }

What I have tried

ATTEMPT 1

Set the error document path to index.html as suggested here and it allows the pages to be serve but still returns a 404 when you look in developer tools. This happens because the page refreshes the requested page cannot be found but the angular routing takes place and finds the requested page. Having a 404 is far from ideal so I continued looking

ATTEMPT 2

I saw this suggestion and altered my app-routing.ts as shown below

    imports: [RouterModule.forChild(routes, { useHash: true})],

ATTEMPT 3

I found this solution but it didn't really apply to my situation as they serve their application through a CDN, which is not what I need at this time

ATTEMPT 4

This suggestion did not work for me. I tried creating a routes.json then found that is deprecated and added staticwebapp.config.json neither worked for me

Any help or suggestions will be greatly received

Ling answered 5/5, 2021 at 6:11 Comment(3)
I just can point you out that except for the hash location strategy which is mentioned in attempt 2 there is no other option in Angular level which could help you. This problem is solved by means of the webserver config. In this case - AzureBlockus
@Blockus thanks for the comment. I guess I wasn't very clear in my question, I am not looking for an Angular based solution. I am trying to work out what configuration I have missed in azure to allow my SPA to work correctly. I will update my question accordingly. ThanksLing
Just to make it clear attempt 4 is about Azure Static Web apps, not blob storage with static hosting enabled, therefore that won't work anyway. I also had the same issue and using attempt 1 as the solution. If you don't want 404 and hashing then using a CDN with a rule is the only option I think. Because blob storage static hosting is not specifically created for SPAs, but we are using that as an option. Therefore I think you didn't miss anything and it is how blob storage static hosting works for SPAs which has routes.Tallis
E
2

You cannot use Azure Blob Storage with Static Site feature if you use Angular routing / SPA as it is not designed for that. So that's the answer to your question.

... And that's why Microsoft released Azure Static Web App

Regarding your attempt #4, which is the right approach (so, not related to your initial question). So you should post another question related to Azure Static Web App and provide some details of what you have tried to work with Angular routing.

I tried with "staticwebapp.config.json" and followed Microsoft documentations, I didn't get any issue for my Angular SPA application

Entrain answered 11/3, 2022 at 4:59 Comment(5)
Sadly, the Azure Static Web App seems to be some kind all-in-one solution. I have my API's in several App Services. With the Static Web App I can't connect to them, I also can't route to them, since redirects do not work outside of the app dir.....Vinegarish
It's an all-in-one solution but you do not have to use each brick. Have you checked your global headers settings? I am on the same situation like you (like much of people having API backend on app services instead of Function App), I do not have any issue. I guess you have a CORS issue. You can check on ms docs: learn.microsoft.com/en-gb/azure/static-web-apps/… Or post another question for your issueEntrain
so you use headers to route to different api-hosts? Interesting... Do you have an example of how that would work?Vinegarish
aa never mind, I get it now. I think that what I am trying is different. I want to call API's on the local / relative path on the app (say /api/whatever/**). Then I want to route it on the server to the appropriate backend for the env im on. I used to do this on a app service using web.config. Then, i looked into the proxy option of azure functions. But that has been removed. Then I was pointed at Static Web Apps. But they don't seem to be able to fullfill this usecase. (please correct me if i'm wrong :-)Vinegarish
@RemcoVlierman, you might refer to this repo if you would like to get back proxy feature from Azure Function v4. github.com/shibayan/AppServiceProxy.SiteExtension I heard that a lot of people complain about losing the proxy feature and pushing dev to use API Management Services (which is not totally the same in my opinion)... So Microsoft might reconsider putting this feature backEntrain

© 2022 - 2024 — McMap. All rights reserved.