Simple guide to setup React as the view layer for AdonisJS using InertiaJS (https://github.com/eidellev/inertiajs-adonisjs).
This is a rough setup guide, I intend to do a more fleshed out blog post style guide in future, or maybe even a generator.
Feel free to open a PR or issue with comments / suggestions.
This repo is a working example, do the following to see it in action:
git clone git@github.com:kevinchar93/csr-adonis-inertia-react.git cd csr-adonis-inertia-react npm install node ace serve --watch Navigate to http://127.0.0.1:3333
Based on:
- https://dev.to/eidellev/getting-started-with-adonisjs-and-inertia-js-2po0
- https://github.com/eidellev/inertiajs-adonisjs
- https://adocasts.com/lessons/adding-inertiajs-to-a-new-adonisjs-project
npm init adonis-ts-app@latest csr-adonis-inertia-react ❯ Select the project structure · web ❯ Enter the project name · csr-adonis-inertia-react ❯ Setup eslint? (y/N) · true ❯ Setup prettier? (y/N) · true ❯ Configure webpack encore for compiling frontend assets? (y/N) › true npm i @eidellev/inertia-adonisjs@7.4.1 node ace configure @eidellev/inertia-adonisjs ❯ Enter the edge file you would like to use as your entrypoint · app ❯ Would you like to install the Inertia.js client-side adapter? (Y/n) · true ❯ Would you like to use SSR? (y/N) · false ❯ Which client-side adapter would you like to set up? · @inertiajs/inertia-react Add Inertia middleware to start/kernel.ts:
Server.middleware.register([ () => import('@ioc:Adonis/Core/BodyParser'), () => import('@ioc:EidelLev/Inertia/Middleware'), ]);By default Webpack Encore (AdonisJS asset bundler) is configured for JS, we want to use TS in our app, let's configure support for TS.
Install ts-loader and @babel/preset-react so Encore knows how to bundle Typescript files and JSX syntax.
npm install ts-loader @babel/preset-react --save-devModify the entrypoint, edit webpack.config.js changing the following:
Encore.addEntry('app', './resources/js/app.js')into:
Encore.addEntry('app', './resources/js/app.tsx') Encore.enableTypeScriptLoader() Encore.enableReactPreset()Rename ./resources/js/app.js to ./resources/js/app.tsx.
Create a file ./resources/js/tsconfig.json, with contents:
{ "include": ["**/*"], "compilerOptions": { "lib": ["DOM"], "jsx": "react", "esModuleInterop": true } }Also in the file tsconfig.json at the root of your project add the following to the "compilerOptions" section
"lib": ["DOM"], "jsx": "react", This is to prevent warnings about using jsx syntax in your .tsx files down resources\js & so you can use the document object directly without errors.
Running the config script earlier for the Inertia JS Provdier (node ace configure @eidellev/inertia-adonisjs) should have generated this file: resources\views\app.edge.
Its contents should be:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="icon" type="image/png" href="/favicon.ico"> @entryPointStyles('app') @entryPointScripts('app') <title>csr-adonis-inertia-react</title> </head> <body> @inertia </body> </html>Now configure the app entrypoint file resources/js/app.tsx to contain:
import { InertiaApp } from '@inertiajs/inertia-react' import React from 'react' import ReactDOM from 'react-dom' import '../css/app.css' // initial page object with props from server const root = document.getElementById('app') const page = JSON.parse(root?.dataset.page as string) // dynamically load specified page component from "resources/js/Pages/." dir async function resolver(pageName) { const module = await import(`./Pages/${pageName}`) return module.default } function App() { return <InertiaApp initialPage={page} resolveComponent={resolver} initialComponent={''} /> } ReactDOM.render(<App />, root)Create a test component resources/js/Pages/Test.tsx, with contents:
import React from 'react' const Test = ({exampleProp}) => <div>Hello world, from {exampleProp}!)</div> export default TestCreate a test route start/routes.ts, contents:
import Route from '@ioc:Adonis/Core/Route' Route.get('/test', async ({ inertia }) => { return inertia.render('Test', { exampleProp: 'inertia' }) }) Boot up your server with node ace serve --watch & navigate to http://127.0.0.1:3333/test
Voilà! ...you should now have a page rendered using React + Inertia JS served by your Adonis JS application.