I’m trying to integrate React-Admin
AdminDashboard
component into a larger React application that uses React-Router for navigation. However, I’m encountering issues where AdminDashboard
doesn’t render or work as expected.
When I initially had the AdminDashboard
directly in App.js
, everything functioned correctly, and the URL displayed as "http://localhost:3000/AdminDashboard/#/users"
. However, after refactoring AdminDashboard
into a separate component, the page fails to load, and the URL changes unexpectedly to "http://localhost:3000/users"
or "http://localhost:3000/posts"
as comes first in Resources.
This issue began only after moving the AdminDashboard
code into its own component, indicating a potential problem with how the routing or component integration is handled.
I first made the app like Blog.logrocket
Before refactoring AdminDashboard.jsx
wasn’t a separate component and it was inside app.js like the code down below:
//here all the imports
const app = () => {
return (
<Admin dataProvider={dataProvider}>
<Resource name="posts" list={PostList} />
<Resource name="users" list={UserList} />
</Admin>
);
};
// exporting the app, and all this was working fine
Below is my latest code setup and its not working:
AdminDashboard.jsx:
import React from 'react';
import { Admin, Resource } from 'react-admin';
import UserList from './User';
import PostList from './Posts';
import restProvider from 'ra-data-simple-rest';
const dataProvider = restProvider('http://localhost:3000');
const AdminDashboard = () => {
return (
<Admin dataProvider={dataProvider}>
<Resource name="posts" list={PostList} />
<Resource name="users" list={UserList} />
</Admin>
);
};
export default AdminDashboard;
App.js:
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Header from "./components/Layout/Header";
import Footer from "./components/Layout/Footer";
import Homepage from "./components/Homepage";
import NotFound from "./components/Layout/NotFound";
import PrivateRoute from "./components/Routing/PrivateRoute";
import Login from "./components/Admin/Login";
import AdminDashboard from "./components/Admin/AdminDashboard";
const App = () => {
return (
<Router>
<div className="App">
<Routes>
<Route path="/" element={<LayoutsWithHeader />}>
<Route path="*" element={<NotFound />} />
<Route exact path="/" element={<Homepage />} />
<Route path="/login" element={<Login />} />
<Route element={<PrivateRoute />}>
<Route path="/AdminDashboard/*" element={<AdminDashboard />} />
</Route>
</Route>
</Routes>
</div>
</Router>
);
};
const LayoutsWithHeader = () => {
return (
<>
<Header />
<Outlet />
<Footer />
</>
);
};
export default App;
range.js
module.exports = (req, res, next) => {
res.header("Content-Range", "users 0-20/20");
res.header("Content-Range", "Posts 0-20/20");
next();
};
My latest code structure :
appname/
├── client/ # Client-side React application
│ ├── public/ # Static files
│ ├── src/
│ │ ├── components/
│ │ │ ├── Admin/
│ │ │ │ ├── AdminDashboard.jsx # Admin dashboard component
│ │ │ │ ├── Login.jsx # Login component
│ │ │ │ ├── Posts.jsx # Posts component
│ │ │ │ └── Users.jsx # Users component
│ │ │ ├── Layout/
│ │ │ │ ├── Footer.jsx # Footer layout component
│ │ │ │ ├── Header.jsx # Header layout component
│ │ │ │ └── NotFound.jsx # Not found component
│ │ │ ├── Routing/
│ │ │ │ └── PrivateRoute.jsx # Private route component
│ │ │ └── Homepage.jsx # Homepage component
│ │ ├── App.css # Main CSS file for the app
│ │ ├── App.js # Main JavaScript file for React app
│ │ ├── App.test.js # Test file for the app
│ │ ├── index.css # CSS file for index component
│ │ ├── index.js # Entry point for React app
│ │ ├── logo.svg # Logo file
│ │ ├── reportWebVitals.js # Web vitals report utility
│ │ └── setupTests.js # Setup file for tests
│ ├── package.json # NPM package file for the client
│ └── node_modules/ # Node modules for the client
│
├── server/ # Server-side Node.js application
│ ├── Controllers/ # Controllers for server logic
│ ├── middlewares/ # Middlewares for the server
│ ├── Models/ # Data models for the server
│ ├── Routers/ # Route definitions for the server
│ ├── config/
│ │ └── config.env # Environment config file
│ ├── node_modules/ # Node modules for the server
│ ├── uploads/ # Uploaded files directory
│ ├── package-lock.json # NPM lock file for server
│ ├── package.json # NPM package file for the server
│ ├── range.js # Additional JavaScript file
│ ├── server.js # Entry point for Node.js server
│ └── db.json # Mock database JSON file
│
├── .gitignore # Git ignore file
├── links.json # Additional JSON file
├── package-lock.json # NPM lock file for root
├── package.json # NPM package file for root
├── README.md # Readme file for the project
└── request.log # Log file for server requests
I’ve examined the routing setup, and while I initially believed it wasn’t the issue, I’m starting to suspect it might be related to the problem after all, given my current understanding.
Extra code and info:
the link in header:
<Link to="/AdminDashboard">
AdminDashboard
</Link>
</>
Part of client-side package.json:
"proxy": "http://localhost:5000",
"dependencies": {
"react": "^18.2.0",
"react-admin": "^4.16.4",
"react-dom": "^18.2.0",
Part of servier-side package.json:
"scripts": {
"server": "json-server --watch db.json --port 5000 --middlewares ./range.js",
"client": "npm start --prefix ./client",
"dev": "concurrently "npm run server" "npm run client""
},
2
Answers
With a URL like
"http://localhost:3000/AdminDashboard/#/users"
implies you were previously using hash routing. The app was served/hosted from"http://localhost:3000/AdminDashboard/#"
and the accessible routes were:"/"
root/home page"/users"
users page"/posts"
posts pageYou then added client-side routing, e.g.
react-router-dom
and use aBrowserRouter
. It seems theBrowserRouter
thinks it is running from"http://localhost:3000"
, so the same routes above work relative to this. I suspect you could just add abasename
prop to the router and edit the "admin dashboard" to omit the path prefix. This configures the router to run under a specific basename in the URL.Example:
Have you tried setting the
<Admin basename>
prop as explained in the Using React-Admin in a route section?By this way, react-admin will include the
basename
in all links.Something like: