bhauman / lein-figwheel

Figwheel builds your ClojureScript code and hot loads it into the browser as you are coding!
Eclipse Public License 1.0
2.88k stars 208 forks source link

Add option to render index.html before 404 #512

Closed rafd closed 7 years ago

rafd commented 7 years ago

A common pattern for SPA sites is to use a client-side router (ex. secretary) and to direct all requests (except those to static resources) to index.html.

The current built-in Figwheel server returns index.html for the server root, and static resources (for files from resources/public/*), but, when used with a client-side router, returns a 404 when a client-routed page is refreshed, forcing the dev to implement a server or use the :ring-handler option.

On many SPA projects, I add a server only for the purpose of fixing this in development (in production, I just rewrite URLs w/ nginx, or with .htaccess rules).

I think I would be useful to have an option to tell the Figwheel server to return the index.html file (if it exists) instead of a 404. For many projects, it would temporarily defer the need for a server, and for some projects, it will completely get rid of that need in development.

In this PR, I add a config option to Figwheel called :force-index (I'm open to suggestions for a better name), which, when set to true, enables a catch-all route (which renders index.html) before the 404.

bhauman commented 7 years ago

So there are a couple of things here:

404 failures are extremely helpful feedback for quickly identifying bad urls. False positives like returning the index.html for a request trying to get a site.css file can be very confusing. "Why isn't the css working? It's loading!"

Another thing worth pointing out is that you do not have to have a separate server to accomplish this. You can add this functionality to your :ring-handler, and I would suggest that you make the functionality so that it only supplies the index.html at the several specific endpoints that your app needs, as to prevent confusing false positives during development.

You can create a simple wrapper (to wrap your routes?) that you can parameterize with paths to return the index.html, that you can reuse, but the code is so minimal that you can code it up ad-hoc as well.

I would say that this is the right approach to allow customization of server behavior for many reasons including the simple fact that the behavior is portable to your production server environment.