Forums

404 routes fallback to index.html

Hello,

I have setup a modern web application in PA with a Flask backend + Angular 6 frontend. I have it almost ready to go live but need to configure the web-server to allow the following behaviour:

  • Flask listens to all URLs in mydomain.com/api/** and returns with an appropriate JSON. This is working OK
  • Angular should listen to all the other routes. In order to achieve this:
  • a ) I have created a static file redirect in PA from my angular folder to the root of the domain, so that when someone navigates to mydomain.com the index.html of angular is served. This is working OK.
  • b) Since angular is a Single Page Application (SPA), the index.html is the only html that does exist, but it is designed to handle all routes (with and without hashtags). So if I navigate to mydomain.com/products/beef angular will render a page for beef products. Now, in order to achieve this, the PythonAnywhere webserver has to return, for all 404 not found URLs the /index.html in the domain root, so that the Angular SPA can handle the rest. This is the point where I am struggling as I do not see the way to configure the webserver to return the /index.html on any 404. Please let me know how can I achieve this.

Please find in the following link some examples from the Angular team on how to do this for Apache, Nginx or IIS: https://angular.io/guide/deployment#routed-apps-must-fallback-to-indexhtml

Thank you

Hmm. I don't think there's any way to do that from our built-in static file handler. However, it should be possible to set it up in Flask -- just have a catch-all route that renders your index.html.

Thanks Giles,

I was considering the Flask solution as plan B because it is less efficient to have Flask dealing with regular files and taking away business logic computing power. But if there is no other way, I will have to do it.

As an optimization to the above solution. I think I could map also as many angular routes as possible in the static files mapper PA has. This way those routes know in advance (non-dynamic routes) can be dispatched without Flask intervention more efficiently. Is this approach correct? Can I use the static files URL mapper to return for various routes always my index.html, and the flask catch all will deal with all the other URLs? Thanks again and great service.

You can have as many static paths as you like pointing to your index file.