Jzohdi
Jzohdi

Reputation: 23

react-admin as a page in Gatsby project

expecting I wanted to include react-admin in a Gatsby project so that I could have a /admin route that will be an interface for the site data.

What happened instead: Using gatbsy new , I setup a boilerplate gatsby project. Then installing react-admin and adding a page into the gatsby project, while following react-admin tutorial, causes gatsby to fail building.

gatsby develop

seems fine and does not crash the app, however

gatbsy build

leads to

WebpackError: Invariant failed

Steps to reproduce: gatsby new _____ npm install react-admin npm install ra-data-simple-rest

gatsby develop = OK gatsby build = Failed

terminal output https://i.sstatic.net/qNXhk.jpg

Related code: Here is a repository that can be cloned to reproduce: https://github.com/jzohdi/react-admin-gatsby-test

Environment Same result on Windows 10 and WSL Ubuntu 18.04

from package.json "gatsby": "^2.22.15", "gatsby-image": "^2.4.5", "gatsby-plugin-manifest": "^2.4.9", "gatsby-plugin-offline": "^3.2.7", "gatsby-plugin-react-helmet": "^3.3.2", "gatsby-plugin-sharp": "^2.6.9", "gatsby-source-filesystem": "^2.3.8", "gatsby-transformer-sharp": "^2.5.3", "prop-types": "^15.7.2", "react": "^16.12.0", "react-admin": "^3.5.5", "react-dom": "^16.12.0", "react-helmet": "^6.0.0"

Upvotes: 2

Views: 551

Answers (2)

jlev
jlev

Reputation: 644

I was able to get react-admin to work inside gatsby with a third strategy, by using the react-router-dom MemoryRouter on a static page. You won't get the browser url updated when you click resources, but it will at least build.

import simpleRestProvider from 'ra-data-simple-rest';

const AdminApp = () => {
  return (
    <MemoryRouter>
      <Admin
        dataProvider={simpleRestProvider(`${API_URL}/admin`, authFetch)}
      >
        <Resource name="orders" list={OrderList} show={OrderShow} />
      </Admin>
    </MemoryRouter>
  )
};

It also required creating individual pages for routes login, logout and auth-callback routes, to actually handle the async functions provided by ra-auth-auth0. Gatsby didn't exactly make it easy to incorporate react-admin, but now it's all integrated and working nicely.

Upvotes: 0

David L
David L

Reputation: 217

From your repository, it sounds like you found the answer, but you don't like it.

Gatsby can't do SSR for react-admin because react-admin depends on running in the browser. To integrate react-admin into Gatsby, you need to generate your admin area as client-only routes.

I'd expect admin areas to be client-only routes anyways, since they would require authentication to view. Populating them with real data at build-time could create data security issues.

In your example repo, you mention these ways to fix the issue. I'm going to record them here for posterity:

1) Replace the offending module with a dummy during SSR 1

This snippet should replace the react-admin module while running server-side rendering, and result in a successful compilation:

exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
  if (stage === "build-html") {
    actions.setWebpackConfig({
      module: {
        rules: [
          {
            test: /react-admin/,
            use: loaders.null(),
          },
        ],
      },
    })
  }
}

2) Use loadable-components2

Instead of importing react-admin components directly, wrap them in the loadable functions. This pulls them out of the HTML-build process and keeps Gatsby from choking on it.

import loadable from '@loadable/component';

const reactAdmin = loadable() => import('react-admin');
const { Admin, Resource } = reactAdmin

Upvotes: 2

Related Questions