devd: Ability to specify 404 page/handler

For better or worse, I’m using react-router with browserHistory on a project which turns hash routes (devd.io/#/foo) into prettier urls (devd.io/foo). This functionality requires specific setup in the server software and I do not believe it is currently possible to configure devd to support this.

The recommended setup for nginx is to use the try_files directive to fall back on your react entry page if the file is not found (try_files $uri /index.html). I believe the simplest way to support this functionality in devd would be to allow for a 404 handler or fallback to be specified when the file server cannot find the specified resource. Perhaps a more robust way would be an extension to the routing syntax to allow for greater flexibility.

Thank you for your consideration

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 5
  • Comments: 24 (11 by maintainers)

Commits related to this issue

Most upvoted comments

Just brainstorming a bit, the global 404 handler would seem to break down when you have a multi-page app which would need to specify different react entry pages for different subtrees. With this in mind, maybe something like a [subtree]!=[endpoint] syntax could be used:

devd -ol . \
  /page2/!=./page2/index.html \
  !=./index.html # global handler (equivalent to /!=./index.html)

With such a syntax, any resource under /page2/ that is not found is served ./page2/index.html, all others are served ./index.html.

I know shells tend to not like the ! character, so this in particular might not work, but I think the general concept is simple enough to not over-complicate the tool but would still offer enough flexibility for these use cases.

@ThomasWeiser I think we have a clear design for this now. I don’t have time to implement it right at the moment, but would gladly merge a patch. If I don’t get an external contribution, I’ll turn to this before the next release.

Here’s the rough design that I think serves all the use cases:

  • A --404file flag that specifies an over-ride when files are not found for static routes. Specifying an over-ride for a non-static route will be an error.

  • The format for the flag is similar to a route specification:

    [hostpath=]404filepath
    
  • If the 404filepath un-rooted or relative (e.g. “notfound.html”, “./templates/notfound.html”), we will look for it up the tree to the base of the static directory

  • If the 404filepath is rooted (e.g. “/notfound.html”), we will only look for the file at the exact path from the static directory base.

So, some examples of valid specifications would be:

For all static routes, look for the file “override.html” in all directories:

--404file override.html

For all static routes, look for “override.html” only at the root:

--404file /override.html

For only the app virtual domain (i.e. app.devd.io) look for “override.html”:

--404file app=override.html

Just as an idea: if --404file argument value starts with / (like “/404.html”), then it would look for file not in current directory but as global 404 page ?

Hi David - to be clear, my proposal here is for the --404file mechanism to only affect local filesystem routes, which means that in your example the REST interface 404s will be left untouched. If you really wanted, you could specify “–404file index.html” to redirect all 404s to the index. We could aso slightly elaborate the scheme, and say that we’ll search for an index over-ride file in parent directories up to the root of the route. I think this quite flexibly covers what is needed, and also leaves room for situations where, for instance, the index file and the 404 override differ.

On windows (and in many use cases on all platforms) one might want to have an actual named over-ride file rather than a symlink.

Does that allay your concerns any?