How to Run React-Admin On Next.Js
More and more developers choose Next.js over Create-React-App (CRA) to boostrap their React project. Next.js uses server-side rendering (SSR), while CRA renders everything client-side. React-admin was designed to run in the client, and the react-admin demos use CRA.
However, react-admin can run seamlessly on Next.js, with minimal configuration.
TL;DR
This article explains how to build a Next.js app for react-admin from scratch. But if you only want the code:
Clone the marmelab/next-react-admin repository. And just build your admin.
That's it!
Setting Up Next.js
Let's start by creating a new Next.js project called nextjs-react-admin
.
npx create-next-app --ts nextjs-react-admin --use-yarn
This will create a project with the following folder structure:
Setting Up React-Admin
Add the react-admin
npm package, as well as a package to connect to the JSONPlaceholder API.
yarn add react-admin ra-data-json-server
All our examples are based on yarn and TypeScript, but you can of course use npm and JavaScript.
Next, create an App.tsx
file with the following content:
// In src/admin/App.tsx
import * as React from "react";
import { Admin, Resource, ListGuesser } from 'react-admin';
import jsonServerProvider from 'ra-data-json-server';
const dataProvider = jsonServerProvider('https://jsonplaceholder.typicode.com');
const App = () => (
<Admin dataProvider={dataProvider}>
<Resource name="users" list={ListGuesser} />
<Resource name="posts" list={ListGuesser} />
</Admin>
);
export default App;
In this example, the react-admin app is only a part of the Next.js app. So it makes more sense to locate the code in a subfolder (/src/admin
). But if you want to use Next.js to run an admin app alone, you can put it directly under /src
.
Everything is now ready for the final step: the fusion of next.js and react-admin.
Creating An Admin Route
Next.js uses a filesystem-based router, built on the concept of pages. Its internal router will associate a route to every file inside the pages
folder, and will render a component that must be exported.
To render the admin application under the /admin
path, create a file called pages/admin.tsx
.
// In pages/admin.tsx
import App from "../src/admin/App";
const AdminPage = () => {
return <App />;
};
export default AdminPage;
Spoiler alert: the previous code doesn't work.
React-admin uses react-router, which does routing client-side, and is not compatible with SSR. The solution is to disable SSR for the /admin
path:
// In pages/admin.tsx
-import App from "../src/admin/App";
+import dynamic from "next/dynamic"
+const App = dynamic(() => import("../src/admin/App"), { ssr: false })
const AdminPage = () => {
return <App />;
};
export default AdminPage
Now it works!
Next Steps
This technique allows to run one (or many!) react-admin app in Next.js. Next.js takes care of all the JS bundling, and simplifies the deployment.
The next step is to use a real API, either an external API (with CORS headers), or an API served directly by Next.js.
Some developers wonder if they can force server-side rendering in react-admin. It's not possible for now. React-admin was designed for admin panels and B2B apps. In these kinds of apps, users browse many pages and keep the app open for a long time. The Single-Page App architecture is perfect for this case, and provides a superior level of performance than SSR. Besides, many optimizations that come free with react-admin (optimistic rendering and updates) are much more complex to implement with SSR apps.
So even if you use a SSR-enabled framework, you should mount react-admin apps as client-side apps.