Azure / static-web-apps

Azure Static Web Apps. For bugs and feature requests, please create an issue in this repo. For community discussions, latest updates, kindly refer to the Discussions Tab. To know what's new in Static Web Apps, visit https://aka.ms/swa/ThisMonth
https://aka.ms/swa
MIT License
320 stars 53 forks source link

Does static web apps support path wildcard rewrite? #803

Open robersonliou opened 2 years ago

robersonliou commented 2 years ago

How can I use route configuration to setup path wildcard write in azure static web apps? For example, I have a website domain: https://myweb.azurestaticapps.net, and file structure like below:

I'd like to use wildcard pattern in rewrite property just as what reverse proxy does.

ex:

I've set route rewrite rules in staticwebapp.config.json but it was not work:

{
  "routes": [
    {
      "route": "/myjs/*",
      "rewrite": "/js/*"
    },
    {
      "route": "imgs/*",
      "rewrite": "/assets/imgs/*"
    }
  ]
}

Is there any way to do this in static web apps? please help, thanks! BTW, I think It would really useful especially when migrating our legacy website into azure static web apps!

mkarmark commented 2 years ago

We currently don't support wildcard paths for rewrite, but can consider supporting that in the future!

ShanonJackson commented 1 year ago

Think this is a pretty critical feature.

Consider applications where some routes are actually served server-side rendered (SSR) (common in NextJS, but also in other frameworks). In this case you would want a route that's SSR'ed to be handled like this. If the route is /users/* for viewing a user profile.

{
     "route": "/users/*",
     "rewrite": "/api/users/*"
}

However, I think this should be handled via capture as well which would make it not just consistent with other hosting platforms but also consistent with azure itself as other azure services would make the syntax roughly look like this.

{
     "route": "/users/{user-id}",
     "rewrite": "/api/users/{user-id}"
}

Which also plans better for nested wildcard support in the future.

ShanonJackson commented 1 year ago

@robersonliou and SWA team.

Sorry there is a easy and straight forward way to do this, follow the SWA Azure front door documentation, then use azure front door's rewrite system which is more advanced.

jwize commented 1 year ago

@ShanonJackson This is a basic requirement for many website that shouldn't need a global CDN service such as front door to resolve. https://website.com/0000011 where the path(0000011) is a configuration code. I can use a staticwebapp.config rewrite to index.html to load the page but I lose my code.

HowardvanRooijen commented 1 year ago

I'm currently porting a website over from Netlify and the only issue I'm facing is the lack of wildcard rewrites. In Netlify I have a number of redirects

/what-we-think/editions/:category/page/:pagenumber/                             /what-we-think/editions/:category/
/blog/page/:pagenumber/                                                         /blog/
/:year/feed/*                                                                   /blog/

These rules affect several hundred pages.

I'd also like to point out the Netlify redirects file format is a very simple line per rule, space separated format... I've found it a much nicer file format than the JSON equivalent. I had to write a .NET Interactive notebook to convert from the Netlify format to the SWA JSON based format: https://gist.github.com/HowardvanRooijen/4d816612fddaabd88e706d0f6642c919

Xriuk commented 1 year ago

This could be useful for redirects too

OzBob commented 10 months ago

@ShanonJackson @anthonychu suggested to use AzFn API for redirects: image

https://johnnyreilly.com/azure-static-web-apps-dynamic-redirects-azure-functions says:

name the single function fallback, so it will be served up at /api/fallback. The code of the function is:

//@ts-check
const { parseURL } = require('ufo');
const routes = require('./redirects');

/**
 *
 * @param { import("@azure/functions").Context } context
 * @param { import("@azure/functions").HttpRequest } req
 */
async function fallback(context, req) {
  const originalUrl = req.headers['x-ms-original-url'];
  if (originalUrl) {
    // This URL has been proxied as there was no static file matching it.
    context.log(`x-ms-original-url: ${originalUrl}`);

    const parsedURL = parseURL(originalUrl);

    const matchedRoute = routes.find((route) =>
      parsedURL.pathname.includes(route.route)
    );

    if (matchedRoute) {
      context.log(`Redirecting ${originalUrl} to ${matchedRoute.redirect}`);

      context.res = {
        status: matchedRoute.statusCode,
        headers: { location: matchedRoute.redirect },
      };
      return;
    }
  }

  context.log(
    `No explicit redirect for ${originalUrl} so will redirect to 404`
  );

  context.res = {
    status: 302,
    headers: {
      location: originalUrl
        ? `/404?originalUrl=${encodeURIComponent(originalUrl)}`
        : '/404',
    },
  };
}

module.exports = fallback;

and staticwebapp.config.json:

  "navigationFallback": {
    "rewrite": "/api/fallback"
  },
  "platform": {
    "apiRuntime": "node:18"
  },
  "routes": [
    {
      "route": "/404",
      "statusCode": 404
    }...

Redirect are driven by an entry in the redirects.js file:

  {
    route: '/2014/01/upgrading-to-typescript-095-personal.html',
    redirect: '/2014/01/09/upgrading-to-typescript-095-personal',
    statusCode: 301,
  },
bennyrowland commented 8 months ago

I would find this feature very useful for my documentation site. I host multiple versions of documentation and it would be nice to allow a latest route which would get whatever the most recent version was. Therefore, I would like to rewrite e.g. latest/{page} to 1_2_1/{page} where each time I publish with a new version I would just update the rewrite rule for latest/{page} (there are too many pages to want to insert individual rewrite rules on a per page level).

Also, because each documentation set is built separately and then combined for publication to the SWA, they currently each deploy and reference their own css/js/etc. files. It would be really nice to be able to rewrite {version}/_static/{page} to _static/{page} and have them share common files. Again, doing this via wildcard rewriting would be much nicer (and less error prone) than crawling over all pages to update every reference to a static resource.

The solution suggested above by @OzBob could be made to work, but it forces a redirect rather than a rewrite - I would much rather a user is able to keep working with latest/* rather than being redirected to a specific version.

@mkarmark you say "can consider supporting that in the future!". Is there any mechanism, other than posting in this issue, for lobbying to get this feature moved up the priority ladder? I really like the SWA paradigm and it otherwise fits really well for my use case, but the lack of this one simple feature is a major stumbling block for me.

danielbayley80 commented 6 months ago

similar for redirects. and given the limit of 20kb for the config file this has made migrating sites and maintaining links near impossible without more coding.