I have created an app using create-react-app with a basename '/admin' and it is working just fine in development mode. All routes working properly both on localhost and behind nginx proxy.
When I build the app using npm run build
I get a blank screen on the '/admin' url, with the following errors in the console:
The script from “https://192.168.1.2/admin/static/js/main.49bb4878.js” was loaded even though its MIME type (“text/html”) is not a valid JavaScript MIME type.
The stylesheet https://192.168.1.2/admin/static/css/main.4efb37a3.css was not loaded because its MIME type, “text/html”, is not “text/css”.
Uncaught SyntaxError: expected expression, got '<' main.49bb4878.js:1
I have tried both <BrowserRouter pathname="/admin">...</BrowserRouter>
and the one I have in the following index.js
file.
It seems like the server sends the index.html
file no matter what the client requests...
This is my index.js
file:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { Provider } from 'react-redux';
import { configureStore } from '@reduxjs/toolkit';
import storeToConfigure from './configureStore';
import CustomRouter from './utils/CustomRouter';
import * as buffer from 'buffer';
import { BrowserRouter } from 'react-router-dom';
console.log(window);
window.Buffer = buffer;
window.process = {}
export const store = configureStore(storeToConfigure);
export const history = createBrowserHistory({ basename: '/admin' });
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<CustomRouter history={history} basename="/thug-app">
<ScrollToTop>
<App />
</ScrollToTop>
</CustomRouter>
</Provider>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint.
reportWebVitals(console.log);
This is the CustomRouter
I'm using, in order to be able to directly access the history
anywhere without a hook:
import React, { useLayoutEffect, useState } from 'react';
import { Router } from 'react-router-dom';
const CustomRouter = ({
basename,
children,
history,
}) => {
const [state, setState] = useState({
action: history.action,
location: history.location,
});
useLayoutEffect(() => history.listen(setState), [history]);
return (
<Router
basename={basename}
children={children}
location={state.location}
navigationType={state.action}
navigator={history}
/>
);
};
export default CustomRouter;
Again, everything works just fine in development. The problem is when I build the app for production. I have tried both pm2
and serve
packages (same names on npmjs). The serve
package returns 404
, while pm2
returns the errors I mention above.
Thank you for taking the time to help!
I managed to make it work with this workaround:
I ditched both
pm2
andserve
and used a customexpress.js
server.The setup:
It also seems to work fine without the following line:
Like I had noticed, both
pm2
andserve
sent theindex.html
file no matter what the client requested.Seems to be working fine behind nginx proxy as well.
Whenever the requested file does not exist, simply serve the index.js file.