Search code examples
javareact-routerreact-reduxdropwizardbrowser-history

Configuration changes in dropwizard application to work with react browserHistory


I have a react app running on a dropwizard server. The bundle.js is served on /ui. When I open the url on /ui and navigate the app(and goto /ui/content), it works fine. But when I try to refresh a specific page like /app/content, it gives a 404.

I know about client side rendering and server side rendering and also that I need to do a GET call for /ui and route the rest on client side, but I couldn't find any documentation for how to do it in dropwizard.

I also know using hashHistory in place of browserHistory will work(as the hash part of the url is not sent to the server), but I wanted to know if this can be done with browserHistory.

There is documentation on how to configure an express sever but I could not find anything for a jetty/dropwizard.


Solution

  • At the Dropwizard level, one thing you can use a use servlet filter to rewrite the URL. One popular implementation is the Tucky UrlRewriteFilter. You would implement it as follows:

    1. Register the filter with Dropwizard:

      @Override
      public void run(ExampleConfiguration configuration, Environment environment) {
          FilterRegistration.Dynamic registration = environment.servlets()
                  .addFilter("UrlRewriteFilter", new UrlRewriteFilter());
          registration.addMappingForUrlPatterns(null, true, "/*");
          registration.setInitParameter("confPath", "urlrewrite.xml");
      }
      
    2. Add the urlrewrite.xml configuration file to your src/main/resources, adding a rewrite rule

      <urlrewrite>
          <rule>
              <from>^/(?!(api|static/|manifest\.json|assets-manifest\.json|favicon\.ico)).*$</from>
              <to type="forward">/index.html</to>
          </rule>
      </urlrewrite>
      

      The above rule states that if the request path matches the above regex, then forward the request to the index.html file. What I used to test was the create-react-app, where the output is a few of those files listed in the matcher. Those files should not be forward.

      The regex uses a negative lookahead, so it's like a negation. It may look like I'm saying that if the path matches those files, then forward, but it's actually the opposite. If you are not using the create-react-app, then your regex will look different. The point is to negate the files you don't want forwarded.

    I put together a working demo. Check out the GitHub repo.