Problem description:
I am trying to setup a boilerplate app that I can use for creating React front-end apps. I am trying to use React Router and for the most part it works well; however, I'm struggling with any route that has multiple subdirectories but only when I manually type them. For example:
127.0.0.1:8080 ==> Works
127.0.0.1:8080/help ==> Works
127.0.0.1:8080/level1/level2 ==> fails
When I click on the link from the Header component, it takes me to the route and calls the correct component; however, if subsequently I refresh page (Google Chrome) or simply type the same exact URL, it does not work and the console shows this error (where bundle.js is the file generated by webpack):
GET http://127.0.0.1:8080/level1/bundle.js net::ERR_ABORTED 404 (Not Found) enter image description here
This is the code:
App.js
import React from 'react';
import * as ReactDOMClient from 'react-dom/client';
import AppRouter from './routers/AppRouter';
console.log('app.js is running');
const appRoot = document.getElementById('app');
const root = ReactDOMClient.createRoot(appRoot);
root.render(<AppRouter />);
AppRouter.js
import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import DashboardPage from '../components/DashboardPage';
import Header from '../components/Header';
import TwoLevelsPage from '../components/TwoLevels';
import NotFoundPage from '../components/NotFoundPage';
const AppRouter = () => (
<BrowserRouter>
<div>
<Header />
<Routes>
<Route path="/" element={<DashboardPage />} />
<Route path="/help" element={<HelpPage />} />
<Route path="/level1/level2" element={<TwoLevelsPage />} />
<Route path="*" element={<NotFoundPage />} />
</Routes>
</div>
</BrowserRouter>
);
export default AppRouter;
Header.js
import React from 'react';
import { NavLink } from 'react-router-dom';
const id = '910';
const getCourse = `/getcourse/${id}`;
const Header = () => (
<header>
<h1>THIS IS MY PERSONAL BOILERPLATE APP</h1>
<NavLink
to="/"
className={({ isActive }) => 'nav-link' + (isActive ? ' is-active' : '')}
>
Home
</NavLink>
<NavLink
to="/help"
className={({ isActive }) => 'nav-link' + (isActive ? ' is-active' : '')}
>
Help{' '}
</NavLink>
<NavLink
to="/level1/level2"
className={({ isActive }) => 'nav-link' + (isActive ? ' is-active' : '')}
>
L1L2
</NavLink>
</header>
);
export default Header;
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Boilerplate</title>
</head>
<body>
<div id="app"></div>
<script src="./bundle.js"></script>
<p>This is the subtitle straight from HTML</p>
</body>
</html>
package.json
{
"name": "boilerplate",
"version": "1.0.0",
"main": "index.js",
"author": "me",
"license": "MIT",
"scripts": {
"build": "webpack",
"dev-server": "webpack-dev-server"
},
"dependencies": {
"@babel/preset-env": "^7.18.2",
"@babel/preset-react": "^7.17.12",
"babel-loader": "^8.2.5",
"babel-plugin-transform-class-properties": "^6.24.1",
"node-sass": "^7.0.1",
"normalize.css": "^8.0.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-modal": "^3.15.1",
"react-router-dom": "^6.3.0",
"webpack": "^5.73.0",
"webpack-dev-server": "^4.9.2"
},
"devDependencies": {
"@babel/cli": "^7.17.10",
"@babel/core": "^7.18.5",
"css-loader": "^6.7.1",
"sass-loader": "^13.0.2",
"style-loader": "^3.3.1",
"webpack-cli": "^4.10.0"
}
}
webpack.config.js
const path = require('path');
module.exports = {
mode: 'development',
entry: './src/app.js',
output: {
path: path.join(__dirname, 'public'),
filename: 'bundle.js',
},
module: {
rules: [
{
loader: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/,
},
{
test: /\.s?css$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
],
},
devtool: 'eval-cheap-module-source-map',
devServer: {
static: path.join(__dirname, 'public'),
historyApiFallback: true,
},
};
Any help would be greatly appreciated. This is my first post so if I didn't provide appropriate information then please let me know.
Thanks in advance!