Skip to content

Instantly share code, notes, and snippets.

@irwing-reza
Last active January 27, 2024 10:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save irwing-reza/0f15f7c7ffb14c8aa2a09edbd2942c31 to your computer and use it in GitHub Desktop.
Save irwing-reza/0f15f7c7ffb14c8aa2a09edbd2942c31 to your computer and use it in GitHub Desktop.
Adonisjs Inertia SSR React Typescript

Credit to for JS Setup

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?'

  1. Configure Encore:
node ace configure encore
  1. Install @eidellev/inertia-adonisjs package:
npm i -S @eidellev/inertia-adonisjs
  1. Configure @eidellev/inertia-adonisjs package:
node ace configure @eidellev/inertia-adonisjs
  1. Install the missing @inertiajs/core
npm i -S @inertiajs/core`
  1. Add Inertia middleware to start/kernel.ts:
Server.middleware.register([
  () => import('@ioc:Adonis/Core/BodyParser'),
  () => import('@ioc:EidelLev/Inertia/Middleware'),
]);
  1. 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} />)
  },
})
  1. 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} />,
  });
}
  1. Install @babel/preset-react and @babel/preset-typescript
npm i -D @babel/preset-react @babel/preset-typescript
  1. Enable React and Typescript presets at webpack.config.js AND webpack.ssr.config.js
Encore.enableBabelTypeScriptPreset()
Encore.enableReactPreset()
  1. Rename app.js to app.tsx at webpack.config.js
Encore.addEntry('app', './resources/js/app.tsx')
  1. Rename ssr.js to ssr.tsx at webpack.ssr.config.js
Encore.addEntry('ssr', './resources/js/ssr.tsx')
  1. Add @inertiajs/core and @inertiajs/react to allowlist at webpack.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.

  1. 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
  1. Change ./start/routes.ts to use inertia and render our recently created page:
Route.get('/', async ({ inertia }) => inertia.render('Index', { title: 'Hello World!' }))
  1. Enable jsx on your tsconfig.json, add this inside compilerOptions
"compilerOptions": {
    ...otherOptions,
    "jsx": "react",
}
  1. Lastly, compile the files using both (in two separated terminals) following commands:

Terminal 1:

npm run dev

Terminal 2:

node ace ssr:watch

Optional

If you don't want to import React on all your components

  1. Add webpack require at the top of your webpack.config.js and webpack.ssr.config.js
const webpack = require('webpack')
  1. Include ProvidePlugin Config on webpack.config.js and webpack.ssr.config.js
Encore.addPlugin(
  new webpack.ProvidePlugin({
    React: 'react',
  })
)
  1. Update jsx on your tsconfig.json
From:
"compilerOptions": {
    ...otherOptions,
    "jsx": "react",
}
To:
"compilerOptions": {
    ...otherOptions,
    "jsx": "react-jsx",
}
  1. Remove import React from 'react' from your .tsx files
  2. Lastly, compile the files using both (in two separated terminals) following commands:

Terminal 1:

npm run dev

Terminal 2:

node ace ssr:watch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment