- Install Adonisjs Web
yarn create adonis-ts-app hello-world
❯ Select the project structure · web
❯ Enter the project name · hello-world
❯ Setup eslint? (y/N) · false
❯ Configure webpack encore for compiling frontend assets? (y/N) · true
- Install inertia
yarn add @eidellev/inertia-adonisjs
node ace configure @eidellev/inertia-adonisjs
❯ Enter the `.edge` view file you would like to use as your root template · app
❯ Would you like to use SSR? (y/N) · false
❯ Which client-side adapter would you like to set up? · @inertiajs/react
[ wait ] Installing dependencies: @inertiajs/react, react, react-dom, @types/react, @types/react-dom ..
- Register Inertia middleware
// start/kernel.ts
Server.middleware.register([
() => import('@ioc:Adonis/Core/BodyParser'),
() => import('@ioc:EidelLev/Inertia/Middleware'),
]);
- Configure Webpack-Encore for React in Typescript: 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.
yarn add ts-loader @babel/preset-react --save-dev
=> have file resources\views\app.edge.
<!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>
- Modify the entrypoint, edit webpack.config.js changing the following:
// webpack.config.js
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.
resources/js/app.tsx.
// Create a file ./resources/js/tsconfig.json, with contents:
{
"include": ["**/*"],
"compilerOptions": {
"lib": ["DOM"],
"jsx": "react",
"esModuleInterop": true
}
}
// tsconfig.json at the root of your project add the following to the "compilerOptions" section
"lib": ["DOM"],
"jsx": "react",
- 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
import React from 'react'
const Test = ({exampleProp}) => <div>Hello world, from {exampleProp}!)</div>
export default Test
- Create a test route
// start/routes.ts
import Route from '@ioc:Adonis/Core/Route'
Route.get('/test', async ({ inertia }) => {
return inertia.render('Test', { exampleProp: 'inertia' })
})
* show result
* Errors
- TS2688: Cannot find type definition file for 'pino-std-serializers'.
yarn add @types/pino-std-serializers
- TS2307: Cannot find module '@inertiajs/inertia-react'
yarn add @inertiajs/inertia-react
- Error: Can't resolve '@inertiajs/inertia'
yarn add @inertiajs/inertia
- Warning: React-dom.development.js:86: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17
// update resources/js/app.tsx
import { InertiaApp } from '@inertiajs/inertia-react';
import React from 'react';
import { createRoot } from 'react-dom/client';
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={''} />;
}
createRoot(root).render(<App />);
Source git: https://github.com/phong2018/learning-adonisjs-web-inertia
Reference: guide
Thank you.
