Hosting SPA with Static Website option on Azure Blob Storage (clean URLs and Deep links)
Asked Answered
E

3

21

I have succesfully set up a static website on Azure Blob storage using the $web container as advised within the Microsoft documentation. In addition, I have defined index.html for both the 'Index Document Name' and the 'Error Document Name'. This is because I want my JavaScript application to handle the 404 responses.

However, when looking at the network tab in Chrome, I can see that a 404 is being thrown for the URL that I am requesting, despite the page actually working.

My theory is as follows:

  • Azure checks to see if the 'file' exists
  • If the file exists, it returns it
  • If the file doesn't exist, it throws a 404 and rewrites the url to the 'Error Document Name' i.e. index.html in my case (hence my pages still work)

The problem I have is that my URLs are clean urls, for example:

/activities/some-slug is never going to exist as a file, this just tells my JavaScript application where to route the request i.e. what view to load.

Just to be clear, the page does work because it is still routing 404 errors to index.html.

How can I tell Azure blob to just route absolutely everything to index.html and let my app throw the 404 if necessary?

We do have a Premium Verizon CDN set up already because I was not originally aware of the static website option on Azure Blob. If the CDN is the best route, please can you provide instructions on how to configure the CDN to provide what I am looking for?

What I have tried/researched

I have read numerous articles (specifically the comments in this one) and I believe that there may be various solutions i.e. Azure Functions, Proxy, CDN etc. That said, none provide clear instructions of what to actually do with those specific services.

I usually work on AWS so am not familiar with all of the Azure services and available configurations.

Extrapolate answered 27/11, 2019 at 14:23 Comment(3)
Did you ever find a solution for this? Because I am in the same boat as you, and I was just about to follow the same approach you did, but I don't want 404 status codes actually being thrown. I just want to catch every URL with my SPA.Refund
@Lev - I am not familiar enough with Azure to know all of the potential solutions but I am confident that there are various choices. Fortunately for me, we require the Premium CDN (for other reasons), and this offers the required rewrite functionality to achieve what I need.Extrapolate
Actually, I found the solution last night as well. It is the rewrite URL functionality, which is now a part of the Standard Microsoft CDN plan. All the references and documentation suggests you need the premium plan, but it was added to the standard plan some time last year. :)Refund
P
39

I think I found a solution

  1. Add a new rule
  2. Condition: URL file extension

    a. Operator: Less than

    b. Extension: 1

    c. Case transform: No transform

    [This basically means that the URL requested has no file (extension) but is a route of the app which will be taken care of by the app routing]

  3. Action: URL rewrite

    a. Source pattern: /

    b. Destination: /index.html

    c. Preserve unmatched path: No

  4. Save rule

Screenshot.

Place answered 29/1, 2020 at 20:5 Comment(8)
This is an excellent answer, just for understanding why did you choose 302 and not 301 for HTTP to HTTPS redirect?Maxima
As we are using a SPA, I don't want crawlers to replace a specific route with index.html, but rather maintain the current route. Therefor I am using 302 instead of 301. Also see this Microsoft Docs tutorial: learn.microsoft.com/en-us/azure/cdn/cdn-standard-rules-enginePlace
Thanks for the solutions. Using CDN with blob storage is enough now. No need to use the static website feature in blob storage. Plus we can use many containers in the same blob storage for more than one static website.Toratorah
I apologise for not reviewing/accepting this sooner, I must have missed when you posted it. I am trying to refresh my memory as to what exactly it was I was trying to achieve as your solution is very different to mine and I am therefore getting confused by my original question. When I have time, I'll post up my solution, and I can dive deeper into ascertaining which is better. In the meantime, I'll accept this as the answer :-)Extrapolate
Clear, concise answer that works beautifully with my code-split create-react-appUnfix
If you're having trouble finding where the heck is the "Add rule" page you're not alone! 1 - Click on the 'Azure CDN' tag (below Static Website). 2 - Create a new CDN Profile (be careful to select the WEB link and not BLOB. 3 - Enter the newly CDN profile on 'All Resources'. 4 - Click on the single endpoint you see in 'Overview'. 5 - Click on 'Rules Engine'. There you go, you can now see perfectly the screen Andreas is speaking ofPrithee
What about js/css dependencies from the index.html? They're still trying to load with a path relative to the original url.Bake
Routes containing a file extension (e.g. contoso.com/styles.css) are not affected by this rule. They are obtained from the origin as is.Place
S
6

Kudos to Andreas Wendl at https://github.com/MicrosoftDocs/azure-docs/issues/43257#issuecomment-580668444

Here's a simpler / possibly more correct solution:

enter image description here

  • leave /static/* be
  • rewrite everything else to /index.html

So, index.html is served in response to deep links like /users/ and let's say /users/alexa.siri.

Sekofski answered 12/5, 2020 at 2:1 Comment(0)
F
1

Thanks @Dima Tisnek for the shorter answer. Here's the answer in plaintext (the edit queue is full for that answer):

Azure Endpoint Resource > Rules engine > Add rule

Name: spa

  1. If URL Path [Operator: Not begins with] [Value: /static/] [Case transform: No transform]
  2. then URL rewrite [Source pattern: /] [Destination: /index.html] [Preserve unmatched path: No]
  3. and then cache expiration [Cache behavior: Override] [Days: 0] [Hours: 0] [Minutes: 5] [Seconds: 0]

rules described above

Franklinfranklinite answered 12/10, 2022 at 19:50 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.