FallbackRoute Matches not working as expected

I’ve been scratching my head trying to figure out how to get my SPA FallbackRoute to ignore /api requests (I like my api endpoints at /api, so my SPA can live at /).

I’ve seen this post PageTemplate, Service and default route

Based on the documentation, we can add to RequestRules, so I created a naive IsNotApi Rule (which just checks if the route contains /api) - your AcceptsHtml one actually makes more sense, but it never worked. So I tried overriding the default AcceptsHtml with my own and setting breakpoints.

Code

Add /api to all Dtos
Startup.cs.GetRouteAttributes

public override RouteAttribute[] GetRouteAttributes(Type requestType)
        {
            var routes = base.GetRouteAttributes(requestType);
            routes.Each(x => x.Path = "/api" + x.Path);
            return routes;
        }

Startup.cs.Configure
Remove old, copy / paste implementation, set breakpoint

        Config.RequestRules.Remove("AcceptsHtml");
        Config.RequestRules.Add("AcceptsHtml", request =>
            {
               //This never gets hit. If I navigate to http://localhost:5000/dashboard in my SPA, then hit F5 (refresh) - I get a 404. But /api/states and /api/states.json returns a list of states
                return request.Accept?.IndexOf(MimeTypes.Html, StringComparison.Ordinal) >= 0;
            });

Fallback

[FallbackRoute("/{PathInfo*}", Matches = "AcceptsHtml")]
    public class FallbackForClientRoutes
    {
        public string PathInfo { get; set; }
    }

    public class MyServices : Service
    {
        //Return index.html for unmatched requests so routing is handled on client
        public object Any(FallbackForClientRoutes request) =>
            new PageResult(Request.GetPage("/"));
    }

The breakpoint is never hit, even though my browser request is in fact a text/html request.

All I want is for my true API to live in /api, and my SPA to live at /. Is there any easier way?

If I remove all the above code, and change HostConfig.HandlerFactoryPath to “api”, the only way my SPA loads is via http://localhost:5000/api/api.

I’d personally just be prefixing your routes with /api as it’s more explicit and not reliant on dynamically change them that’s hidden elsewhere, either way it looks like your GetRouteAttributes() is also changing the route for FallbackForClientRoutes DTO no?

You also don’t want to set Config.HandlerFactoryPath.