Gp17
Gp17

Reputation: 113

Asp.net core web application with react template: in development, server checks mvc routes first, but in prodcution the server only returns index.html

I am trying to migrate an existing MVC application that uses razor pages into web API + ReactJS client. I'm doing this step by step which means I have migrated the homepage (Home/Index) plus a few other pages/features to react. There are links between razor pages and those that are implemented in react. This works perfectly in development environment which runs react development server.

For example in development environment, if I route to localhost:12345/Controller/Action (for an available Controller and action) server executes the respective action and returns the proper view and if I try to access a route which is unknown to server it returns index.html and react-router handles the routing from this point. This is the accepted behavior and works like a charm in the development environment.

But things change when I build the react app and run the application in production mode. The request never reaches the server and is handled on the client-side by react-router. When I hard-refresh the page it triggers the MVC actions as accepted though.

I would like to have the same behaviour it has in development for the production.

This is how the starup.cs file looks like.

        // ConfigureServices
        .
        .
        .
        // In production, the React files will be served from this directory
        services.AddSpaStaticFiles(configuration =>
        {
            configuration.RootPath = "ReactSource/build";
        });
        .
        .
        .


       
        // Configure
        .
        .
        .
        app.UseStaticFiles();
        app.UseSpaStaticFiles();
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller}/{action}");
        });


        app.UseSpa(spa =>
        {
            spa.Options.SourcePath = "ReactSource";

            // do not start the react development server in production
            if (env.IsDevelopment()) { spa.UseReactDevelopmentServer(npmScript: "start"); }
        });
        .
        .

Any Idea what I'm missing here? Should I modify the react-router for this?

Upvotes: 1

Views: 1054

Answers (2)

kazem fallahikhah
kazem fallahikhah

Reputation: 71

To have a Progress Web Application, you must enable the Service worker in your React web app.

For solve cache problem in production mode you must enter following code in index.tsx file:

ReactDOM.render(
    <BrowserRouter basename={baseUrl}>
        <App />
    </BrowserRouter>,
    rootElement);

//index page is Route exact path.
if (window.location.href.includes('index'))
    registerServiceWorker();
else
    unregisterAndReload();

function unregisterAndReload() {
    navigator.serviceWorker.ready.then(registration => {
        registration.unregister().then(() => {
            window.location.reload();
        });
    });
}

and App.tsx file should be like the following:

render() {
        return (
            <Layout>
                <Route exact path='/index' component={Home} />
                <Route path='/contact' component={ContactUs} />
            </Layout>
        );
    }

Upvotes: 1

Gp17
Gp17

Reputation: 113

I solved my problem by turning off (unregistering) the create-react-app out of the box service worker which tried to cache assets and was preventing the requests to reach the server.

In the index.js file, I simply imported { unregister } from "./registerServiceWorker" and replaced registerServiceWorker(); with unregister(); at the end of the auto generated index.js file.

Upvotes: 1

Related Questions