Combining server and client-side routing

Enonic version: 6.15.7
OS: Ubuntu

I am handling the routing in the front-end using react-router-dom lib.

Enonic XP throwns a 404 page if the user tries to copy + paste the URL of a sub-page of the website ( Ex.: http://www.mysite.com/about-us. This happens because JavaScript hasn’t been loaded to the browser yet.

How can we handle the routing with Enonic XP in this case?

I tried to solve this issue with httpClient lib with no luck (obviously) since it uses http protocol to get the assets.

var httpClient = require("/lib/http-client");

exports.handle404 = function(err) {
  var host = "http://www.mysite.com";
  var path = "about-us";

  var response = httpClient.request({ // This method works fine 
    url: host,
    method: "GET"
  });

  var response2 = httpClient.request({ // doesn't work 
    url: host + "/" + path,
    method: "GET"
  });

  // return {
  //   redirect: "/"
  // };

  return {
    body: response.body
  };
};

Thanks!

The question is. … :thinking:

How can we send/redirect all requests to the index.html and preserve the URL in the browser so that the react-router can take over?

something like…

app.get('*', (req, res) => {
 res.sendFile(path.resolve(__dirname), 'index.html)
})

I don’t know enough about React to know if this is the right answer, but in Enonic XP you can use mappings to map a URL pattern to a specific JavaScript controller. For instance, if you map the pattern /.* to some index.js file, then that JavaScript file will run each time you request a URL underneath a site, since the pattern matches any path. As long as you export a get() function in that JS file, that script will process GET requests and can return a response object to the client, in order to start your React app which will then handle the rest from there.

Mappings documentation:
https://developer.enonic.com/docs/xp/stable/cms/mappings

That should at least take care of the “How can we send/redirect all requests” part of your question. As far as preserving the URL in the browser, I’m assuming that’s something that react-router does on its own, I’m guessing using the HTML5 History API or similar.

If you are building a webapp, simply add a js controller using router to handle this. I assume you have completed my first webapp?

@tsi @bhj

Thanks, I will add the controller and test it out.