As i mentioned in my comment, i may have a solution that can fit your needs.
This solution requires an MVC
Controller
and a relevant MapRoute()
.
The general idea is to deliver the index.html
page via MVC
using a controller
and cshtml
and configure on react-router
a basename
when creating browserHistory
.
The key here is that the basename
value must contain the entire path (without the domain) up to the controller
name.
for example:
given this controller
:
public class ReactController : Controller
{
public ActionResult Index()
{
return View();
}
}
and cshtml
:
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8" />
<title>app name</title>
<link href="path/to/file.css/if/needed" rel="stylesheet" />
</head>
<body>
<div id="app"></div>
<script src="path/to/bundle.js"></script>
</body>
</html>
and routeMap
:
routes.MapRoute(
name: "reactApp",
url: "react/{*pathInfo}",
defaults: new { controller = "React", action = "Index", id = UrlParameter.Optional }
);
Now, lets say your app is published under http://example.org/appName/
then you'll need to make sure react-router won't delete the "appName"
portion of the URL when changing it.
for example, if you're in the Home Page - http://example.org/appName/home
and you move to the About Page, you want react-router
to keep the "appName"
like so: http://example.org/appName/react/about
and not like so http://example.org/about
.
Although this will work just fine as you're not posting this URL back to the server, you will face a problem when you will try to go directly to the "About" page. the server will return a 404 when you send the request with this URL: http://example.org/about/
instead of this one: http://example.org/appName/react/about
.
My soulution to this problem is to pass react-router
a basename
that includes the appName
+ sub folders (if any) + the controller name.
I'm using useRouterHistory
and creating the browserHistory
instead of import
it from react-router
const browserHistory = useRouterHistory(createHistory)({
basename: appName
});
the appName
variable is as follow:
const controller = "/react";
const pathName = window.location.pathname;
const appName = pathName.substring(0,pathName.indexOf(controller) + controller.length);
This can be refactored as a function but basically it gets the pathname
up to the controller name (as a convention with your MVC app) including the controller name.
that way react-router
will keep this path on every URL change.
In our case "appName/react"
.