26 August 2019

Routers in modern Javascript framworks usually support path’s similar to a Restful API. I.e. when the main page is localhost:8080 and shows the landing page; then localhost:8080/products/1 might show the page with the details for Product #1. For a single-page application an in-app link to localhost:8080/products/1 should not trigger a reload of the whole application but should be handled within the app. This is the main job of the router.

A lot of Javascript frameworks support this routing based on the browser’s history API. Vaadin Router is just one example. Similar routers exist in Angular and friends.

For this to work, the web-server needs to serve the localhost:8080/index.html for any of these sub-resources/pages. This is because the Router in the Javascript code will deconstruct the URL and show the right page-fragments.

How can this be achived in a JavaEE environment where your front-end Javascript application is packaged inside a WAR-file? Simple. Just use this web.xml:

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
    http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    <error-page>
        <error-code>404</error-code>
    <location>/index.html</location>
    </error-page>
</web-app>

A programatic solution is to use a servlet-filter that always routes to the index.html. Here is from the post on Quarkus and Web UI Development.