Is it possible not to have to hardcode context root to user react-router

1.7k Views Asked by At

Since the concept of web application context root is generally considered as a deployment concern as opposed to a development concern, I'd like to know if it's possible not to hardcode context root in the source code when using React Router for web page navigation.

What I'd like to be able to do is to deploy my web application with any context root as specified by deployment descriptors, e.g. web.xml, without changing any of my React source code.

Below is to follow up on Paul's answer.

First of all, thank you very much Paul. I totally agree that the "basename" property can be used in this regard. And we can use the build scripts to substitute "baseName" with different values that will match the eventual context root specified by the deployment descriptors.

However, I'd argue that doing so will only hide, not change, the fact the context root has to be embedded in the source code which conceptually should be a deployment concern.

I'm very much wondering why React Router has chosen not to resolve the path "/" relative to the context root, i.e. matching "/" to "http://host:port/webapp/", or at least provide an option, e.g.

<Route path="/" relativeToContextRoot="true" …>

After all, treating the actual value of a context root not as a development concern is more a norm than an exception. Would this be a reasonable request to submit to the React Route team?

1

There are 1 best solutions below

2
On

React Router allows you to specify a basename for an application. The basename will be stripped off of the pathname and locations will be matched against the remaining part of the path.

For example, if you set a basename of /mysite, then a request to /mysite/page-one will attempt to match the pathname /page-one against your defined routes.

Setting the basename value dynamically would just be a matter of having the value injected into your code in a manner that would allow your code to access that value while creating the history instance which will be used by your <Router>.

One possible solution would be to set a variable on the window when you are rendering the HTML.

<script>
window.__BASENAME__ = '/some/root';
</script>

You would then be able to access that value in your application when you create your history instance.

const BASENAME = window.__BASENAME__ || '/';
const history = useRouterHistory(createHistory)({
  basename: BASENAME
});