Redirect Rule Doesn't Work for More Than 1 Field

I have an SPA deployed on Netlify with a rule

  from = "/*"
  to = "/index.html"
  status = 200

in my Netlify.toml. I can tell from the logs my rule is recognized.

When I go to my app, doing $URL/stuff works as expected by redirecting to index.html and loading my app; however, when I try to do something like $URL/stuff/morestuff, it loads a blank white page and I can tell from both the network and the sources tabs on Chrome devtools that no redirects are going on. I tried to add additional more refined redirects both before and after my main redirect (which I thought would work for this use case on its own), but it didn’t really fix the problem. What’s the issue here?

Hey @nsadeh

/* catches everything that isn’t an actual file and routes it to your app, irregardless of path depth *(i.e. /this or /this/other/path.) It is up to the app to then handle the routing.

Can you share the site, and even the git repository it is deployed from?


Here is the repo: GitHub - nsadeh/fitness-tracker: A toy Elm app I use to track lifts
The site is located here:

Note that you don’t have an account on the app, so you won’t be able to get past the login page :wink: I am not taking new users on atm.

I ended up getting around this issue by using query parameters in the URL instead of slashes (which were probably the correct way to do this anyways). However, I still want to understand what was broken in the previous version of the deploy with routing.

Previously, the expected behavior was that date/<date> routes to my app, and my code parses the date and displays the appropriate data. However, when playing around with the deployed site with the rule described above, I noticed this behavior:

  1. Any single path parameter worked fine and redirected to my app, which worked as expected given the fallback strategy in the business logic (if the path parameter is not recognized, pretend it is date/<today’s-date>). In the network tab, I could see the 304 status in the index file, and if you watched the sources tab while reloading, you’ll see the folder quickly change to the root folder.
  2. Any double path parameters failed (e.g., stuff/more-stuff, but also date/2022-04-26). In the network tab, there was a 200 status for the index file, and the sources showed that it was trying to read file 2022-04-26 from the date folder (which of course, does not exist).
  3. A single path parameter with a query parameter worked and fell back to the fallback strategy in my app, driving my decision to circumvent this problem (successfully) by rewriting the date logic I had as query parameters instead).

While I have solved the immediate problem, I still think what I did before should work per my understanding of routing rules, so I am curious to see what I did wrong.

So Elm is a foreign language to me :rofl: so I may not offer that many beneficial insights, but here goes.

The below rule is what is used in React, Vue, et. al.

/*   /index.html   200

In Vue routing is configured thus:

  path: '/customers',
  name: 'Customers',
  component: () => import("@/views/Customers"),
  children: [{
    path: ':customer_id',
    name: 'CustomerDetails',
    props: true,
    component: () => import("@/views/CustomerDetails"),

This is all handled inside Vue, such that navigating to /customers or /customers/a-customer-id are routed by Vue to load the appropriate component and fetch data (if required) from a database (this can get more complex with children of children, etc.) There is no need for query parameters.

Again, not knowing Elm it is hard to specify a potential issue, but as long as the Elm JS in index.html is reading the current URL and processing it routing like this should work fine.

I don’t think it’s an Elm/application code issue, because of the described evidence in the network and sources tabs, and because the fallback strategy for unfamiliar paths worked for random single path parameters.

I disagree.

Test for you. Build locally. Use serve to test locally.

Try first in standard mode: serve dist, navigate to /path, and /path/sub/path to see behaviour.
Second, try in SPA mode: serve -s dist and navigate to the same paths.

In the former, you should see 404 messages for any non-existent paths.
In the latter, you should see content from your app, either a data page or internal 404.

Yes, that is exactly the behavior I am seeing.

Is the redirect from your TOML processed during build?

To clarify, in the second (SPA) option, the 404 you saw was from your app, and not from serve?

Yes - I see this message every build. In the second (SPA) option, there were no 404s, as my application logic falls back to a default setting if the path fails to parse as expected. I saw that default behavior.

Hi, @nsadeh. Our support team can investigate this but we would need to be able to reproduce it ourselves or to get detailed data from someone else’s reproduction.

Without hard data, we are only guessing. We will to see the issue occur ourselves or get a recording of the issue to troubleshoot.

Is there some URL you can send us to see the error (for example, on some previous deploy) which does not require a login?

If not, would be make a HAR recording of the issue occurring and post that file here?

Hi Luke, thanks of replying. I captured 2 HAR recordings. One works; it represents going to /data (a route that doesn’t exist in my app, but the redirect rule works so it works fine). The second doesn’t; it represents going to /data/stuff, which works locally in SPA mode (see above troubleshooting with @coelmay ), but not on Netlify. Thanks again for your help!

Edit: I can’t upload HAR files here, and when I try to change the ending to upload it tries to figure out the size so it fails. Is there an email I can send them to?

hi there nsadeh, please put the HAR files in a sharing site like pastebin or make them available via a shared google drive , this has worked for people in the past,thanks!