{
"$type": "site.standard.document",
"canonicalUrl": "https://johnnyreilly.com/posts/azure-static-web-apps-dynamic-redirects-azure-functions",
"description": "Azure Static Web Apps can perform URL redirects using the `routes` section in the `staticwebapp.config.json`. However it is limited. This post will demonstrate dynamic URL redirects with Azure Functions.",
"path": "/posts/azure-static-web-apps-dynamic-redirects-azure-functions",
"publishedAt": "2022-12-22T00:00:00.000Z",
"site": "at://did:plc:yy3apqjlms24kso7ahn7lbmb/site.standard.publication/3mova7c4nho2b",
"tags": [
"azure static web apps",
"azure functions",
"github actions"
],
"textContent": "Azure Static Web Apps can perform URL redirects using the routes section in the staticwebapp.config.json. However it is limited. This post will demonstrate dynamic URL redirects with Azure Functions.\n\n\n\nThe limits of routes in staticwebapp.config.json\n\nI recently found myself fixing up some redirects for my blog, which runs on Azure Static Web Apps. I had quite a few redirects to implement and I ended up with a very large routes section. It was so large that I exceeded the 20kb limit that affect Azure Static Web Apps.\n\nI bemoaned this on Twitter and got some great advice from Anthony Chu who works on Azure Static Web Apps:\n\n[](https://twitter.com/nthonyChu/status/1605248878009208832)\n\nAnthony went on to share details of an example implementation that Nuxt.js has implemented. I took this as a challenge to implement something similar for my blog. Let's see how we got on.\n\nAdding an Azure Function to our Azure Static Web App\n\nThe first thing we need to do is add an Azure Function to our Azure Static Web App. All Static Web Apps can be backed by an Azure Function App. We can create a simple JavaScript HttpTrigger Azure Function following this guide. I used JavScript as it seemed like the simplest option. If we wanted a different language we could use one.\n\nWe're going to name the single function fallback, so it will be served up at /api/fallback. The code of the function is:\n\nWhat's happening here? Well, we're using the ufo package to parse the URL which we grab from the x-ms-original-url header. We then look for a match in our redirects.js, which is a _big_ list of potential redirects.\n\nIf we find a match, we redirect based upon that match. Otherwise we redirect to the custom 404 screen in our app. And we include the original URL in the query string for visibility. (With this in place, any unhandled redirects should show up in Google Analytics etc.)\n\nJSDoc types with @azure/functions\n\nYou'll notice that we're using JSDoc types in the above code and enabling type checking through use of // @ts-check. We're providing types to our function through the @azure/functions package which we've added as a devDependency. You don't have to do this, but it's a nice way to get some type safety.\n\nConsuming the Azure Function from our Azure Static Web App\n\nNow our Azure Function is in place, we need to configure our Azure Static Web App to use it. In our staticwebapp.config.json we'll make some changes:\n\nHere we:\n\n- Point to our apps navigation fallback to our fallback function (/api/fallback) - this will be called whenever a URL is not matched by a static file.\n- We declare an apiRuntime of Node.js 18 - this is the version of Node.js that our Azure Function is using.\n- Whenever the /404 route is hit in our app, we ensure the status code presented is 404.\n- We remove the route redirects we had in place as these will now be handled by /api/fallback (this isn't shown in the above snippet)\n\nDeploying our Azure Function\n\nWe need to deploy our Function, and we achieve that by tweaking the our GitHub Action that deploys our Static Web App. We add the following:\n\nAnd now our Azure Function will be built and deployed alongside our blog.\n\nTesting our Azure Function\n\nWe can demonstrate this works pretty easily. Let's take a super old blog post of mine, where I upgraded to TypeScript 0.9.5 (!!!) The route has changed since I originally posted back in 2014. If we go to https://johnnyreilly.com/2014/01/upgrading-to-typescript-095-personal.html (the old Blogger URL), we'll be redirected (301'd to be specific - signalling a permanent move) to https://johnnyreilly.com/upgrading-to-typescript-095-personal - the new URL. This is demonstrated in the following screenshot - note the location header in the response:\n\nThis particular redirect is driven by [an entry in our redirects.js file:\n\nConclusion\n\nI'd love it if there was a way to do this without an Azure Function. Imagine a staticwebapp.config.js that could be used to configure redirects. That would be awesome. But for now, this is a pretty good solution. Thanks to Anthony Chu for the inspiration and the example. (And thanks to the Nuxt.js team for the example too!)\n\nIf you'd like to see what it looked like when this landed in this very blog, then look at this pull request.",
"title": "Azure Static Web Apps: dynamic redirects with Azure Functions"
}