Originally posted by @brlebtag in eidellev/inertiajs-adonisjs#117 (comment)
Originally posted by @qkab78 in eidellev/inertiajs-adonisjs#117 (comment)
. Create a new adonis project:
npm init adonis-ts-app@latest adonisssr
Don't forget to select web and yes to 'Configure webpack encore for compiling frontend assets?'
- Configure Encore: (Ignore configure encore)
node ace configure encore
- Install @eidellev/inertia-adonisjs package:
npm i -S @eidellev/inertia-adonisjs
- Configure @eidellev/inertia-adonisjs package:
node ace configure @eidellev/inertia-adonisjs
- Install the missing
@inertiajs/core
npm i -S @inertiajs/core`
- Add Inertia middleware to start/kernel.ts:
Server.middleware.register([
() => import('@ioc:Adonis/Core/BodyParser'),
() => import('@ioc:EidelLev/Inertia/Middleware'),
]);
- Create ./resources/js/app.tsx and add the following code:
import React from 'react'
import { createInertiaApp } from '@inertiajs/react'
import { createRoot } from 'react-dom/client'
createInertiaApp({
resolve: (name) => require(`./Pages/${name}.tsx`),
setup({ el, App, props }) {
createRoot(el).render(<App {...props} />)
},
})
- create ./resources/js/ssr.tsx and add the following code:
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { createInertiaApp } from '@inertiajs/react';
export default function render(page) {
return createInertiaApp({
page,
render: ReactDOMServer.renderToString,
resolve: (name) => require(`./Pages/${name}.tsx`),
setup: ({ App, props }) => <App {...props} />,
});
}
- Install @babel/preset-react, @babel/preset-typescript and ts-loader
npm i -D @babel/preset-react @babel/preset-typescript ts-loader@^9.0.0
- Enable React and Typescript presets at
webpack.config.js
ANDwebpack.ssr.config.js
Encore.enableBabelTypeScriptPreset()
Encore.enableReactPreset()
- Rename app.js to app.tsx at
webpack.config.js
Encore.addEntry('app', './resources/js/app.tsx')
- Rename ssr.js to ssr.tsx at
webpack.ssr.config.js
Encore.addEntry('ssr', './resources/js/ssr.tsx')
- Add
@inertiajs/core
and@inertiajs/react
to allowlist atwebpack.ssr.config.js
config.externals = [
require('webpack-node-externals')({
allowlist: ['@inertiajs/core', '@inertiajs/react'],
}),
]
Some people complained that you needed to load require('webpack-node-externals')
to a variable first and then use, like this:
const externals = require('webpack-node-externals')
config.externals = [
externals({
allowlist: ['@inertiajs/core', '@inertiajs/react'],
}),
]
but for me, both ways worked.
- Create a Pages folder at ./resources/js and inside of it, create a Index.jsx (./resources/js/Pages/Index.jsx) and add the following code:
import React from 'react'
const Index = ({ title }) => {
return <div>{title}</div>
}
export default Index
- Change ./start/routes.ts to use inertia and render our recently created page:
Route.get('/', async ({ inertia }) => inertia.render('Index', { title: 'Hello World!' }))
- Enable jsx on your tsconfig.json, add this inside compilerOptions
"compilerOptions": {
...otherOptions,
"jsx": "react",
}
- Lastly, compile the files using both (in two separated terminals) following commands:
Terminal 1:
npm run dev
Terminal 2:
node ace ssr:watch
If you don't want to import React on all your components
- Add webpack require at the top of your
webpack.config.js
andwebpack.ssr.config.js
const webpack = require('webpack')
- Include ProvidePlugin Config on
webpack.config.js
andwebpack.ssr.config.js
Encore.addPlugin(
new webpack.ProvidePlugin({
React: 'react',
})
)
- Update jsx on your
tsconfig.json
From:
"compilerOptions": {
...otherOptions,
"jsx": "react",
}
To:
"compilerOptions": {
...otherOptions,
"jsx": "react-jsx",
}
- Remove
import React from 'react'
from your .tsx files - Lastly, compile the files using both (in two separated terminals) following commands:
Terminal 1:
npm run dev
Terminal 2:
node ace ssr:watch