Unread Notifications

Latest Notifications

No Notifications

You're all set! Start a discussion by leaving a comment on a lesson or replying to an existing comment.

AdonisJS + InertiaJS

How To Add InertiaJS to a New AdonisJS Project

08:55 Watch
6:25 Read

In this lesson, we'll create a new AdonisJS project, then install and configure InertiaJS with Vue 3 using the InertiaJS-AdonisJS adapter.

Watch on YouTube
GitHub
View Repository

InertiaJS provides a unique approach to a monolith application, which they call the “modern monolith.” Essentially it acts as a middleman, aiding in the communication between our server-side and client-side code and opening a gateway for us to easily use Vue, React, and Svelte as the client-side of our monolith.

Now, InertiaJS doesn’t natively support AdonisJS, but it does support third-party adapters. And, thanks to Eidellev, AdonisJS has an adapter called “InertiaJS-AdonisJS” that allows us to easily integrate Inertia into Adonis.

Although we’ll be focusing on Vue 3 for the client-side, InertiaJS does natively support the following frameworks, and more may be supported via third-party adapters.

  • Vue 2

  • Vue 3

  • React

  • Svelte

If you’re looking for server-side rendering (SSR), the InertiaJS-AdonisJS adapter currently only supports SSR with React. SSR is now supported for Vue 2 and 3 in addition to React.

Creating Our AdonisJS Application

The first thing we’ll want to do is create our AdonisJS application, I’ll be naming my project adonis-inertia-example. We’ll want to select the “web” project structure because the InertiaJS-AdonisJS adapter requires @adonisjs/view and @adonisjs/session, which comes pre-configured with the web structure.

Then, we’ll want to include Webpack Encore so we can compile our Vue 3 assets.

npm init adonis-ts-app@latest adonis-inertia-example

# ❯ Select the project structure · web
# ❯ Enter the project name · adonis-inertia-example
# ❯ Setup eslint? (y/N) · false
# ❯ Configure webpack encore for compiling frontend assets? (y/N) · true

Next, we’ll want to change into our project’s directory.

cd adonis-inertia-example

Installing & Configuring the InertiaJS-AdonisJS Adapter

Next, we’ll want to get the InertiaJS-AdonisJS installed and configured within our AdonisJS application. Conveniently, the adapter will also help us get InertiaJS and Vue 3 installed when we configure it into our app.

npm i @eidellev/inertia-adonisjs

With that installed, let’s go ahead and configure it within our AdonisJS application.

node ace configure @eidellev/inertia-adonisjs

# ❯ Select the view you would like to use · app
# ❯ Would you like to install the Inertia.js client-side adapter? · true
# ❯ Would you like to use SSR? · false
# ❯ Which client-side adapter would you like to set up? · inertia-vue3

Select the view you would like to use · app

This is essentially asking what you’d like the Edge file to be called for your InertiaJS app, which the default of app suffices for our use case here.

Would you like to install the Inertia.js client-side adapter? · true

Selecting yes/true here will go ahead and install the client-side implementation of InertiaJS for us, allowing us to skip this step later on.

Would you like to use SSR? · false

Selecting yes here will add server-side rendering to your application.

Note, at the time this lesson was released SSR was not supported. We'll cover SSR down the road. We also have a news post to serve as a quick start if you need SSR now.

Which client-side adapter would you like to set up? · Vue 3

We’ll be using Vue 3 in this series. If you need to use something different, feel free to select whatever tickles your fancy.

That’s all for right now, we’ll circle back with one more step with this adapter here in a moment.

Installing & Enabling Vue Loader

The last thing we’ll need to install is vue-loader.

npm i -D vue-loader

Once that installs, we’ll want to enable it within Webpack Encore. So open up your project within your text editor of choice and open the webpack.config.js file. This will be around line 184, all you need to do is uncomment the Encore.enableVueLoader call below and ensure the version is set to 3.

// webpack.config.js

/*
|--------------------------------------------------------------------------
| Enable Vue loader
|--------------------------------------------------------------------------
|
| Uncomment the following lines of code to enable support for vue. Also make
| sure to install the required dependencies.
|
*/
Encore.enableVueLoader(() => {}, {
  version: 3,
  runtimeCompilerBuild: false,
  useJsx: false
})

Adding the InertiaJS AdonisJS Adapter Middleware

The last thing we need to do with the InertiaJS-AdonisJS adapter is to register its global middleware within our project. So, open your start/kernel.ts file and add the following below your BodyParser middleware.

Server.middleware.register([
  () => import('@ioc:Adonis/Core/BodyParser'),
  () => import('@ioc:EidelLev/Inertia/Middleware'), // 👈
])

With that, we now have the adapter fully configured within our project.

Binding Vue to Inertia

Next, let’s get our Vue app created and connected to Inertia. So, jump into your resources/js/app.js file and plop the below underneath your app.css import.

// resources/js/app.js

import { createApp, h } from 'vue'
import { createInertiaApp } from '@inertiajs/inertia-vue3'

createInertiaApp({
  resolve: name => require(`./Pages/${name}`),
  setup({ el, App, props, plugin }) {
    createApp({ render: () => h(App, props) })
      .use(plugin)
      .mount(el)
  },
})

At the top level, we’re using the createInertiaApp call to initialize our client-side Vue application with InertiaJS. Within this call, we’re passing it two config items.

Resolve

First is resolve, this takes a callback function that’s provided a name. Name here is going to be whatever component name we provide the render call on the server-side. The callback function itself needs to use this to require and return that specific page component. So, here we’ll be looking for all our Inertia Vue pages within the Pages directory.

The Pages directory is relative to the app.js location, so we’ll want to create a folder at resources/js/Pages. This directory will hold all our Vue page components.

While we’re here, let’s go ahead and create our first test page at resources/js/Pages/Home.vue.

<template>
  <h1>Testing</h1>
</template>

Setup

Second is setup, which is a method that’s provided a configuration object containing everything we need to create and mount our Vue 3 application.

First we create create the app, using the render property to render out our Inertia App along with the props. These props will include any data we’re passing along from the server-side.

createApp({ render: () => h(App, props) })

Then, chained off that, we apply a plugin for Inertia, then mount our application. The el provided by the setup configuration will be dynamically generated within our Edge page, called app.edge via an @inertia() tag.

Defining Our First InertiaJS Route

The last thing to do before we boot up our server to test is to register a route to render our Home Inertia page. This will look very similar to using Edge, however, instead of using view.render(), we’ll be using inertia.render().

The inertia property is added onto our HttpContext by the InertiaJS-AdonisJS adapter.

// start/routes.ts

Route.get('/home', async ({ inertia }) => {
  return inertia.render('Home')
})

Just like with Edge, the first argument the render call accepts is the page name to be rendered. Remember our resolve callback is looking inside resources/js/Pages for our pages. So, in order to render our Home.vue component, all we need to provide is Home to the render call.

With that, feel free to go ahead and boot up your server, visible http://localhost:3333/home and give it a go!

Passing Prop Data from Server to Client

Before we sign off, let’s go ahead and ensure our prop data is properly set up as well. Within the /home route we just defined, let’s pass some prop data to our Home component.

This works exactly the same as Edge’s view.render(), where the prop data is the second argument. The main difference here is that view.render() won’t serialize the data. Since, inertia.render() is passing data to client-side JavaScript, it will serialize the data we pass through.

// start/routes.ts

Route.get('/home', async ({ inertia }) => {
  return inertia.render('Home', {
    testing: 'this is a test'
  })
})

Now that we’re passing some prop data to our Home component, let’s make use of it within our Home component! We’ll want to treat this prop data like any other prop when it comes to our Vue component. So, we’ll define it as a prop, give it a type, then we’re free to make use of it within our template.

<template>
  <h1>Testing, {{ testing }}</h1>
</template>

<script>
export default {
  props: {
    testing: String
  }
}
</script>

Go ahead and check out your browser again and you should see Testing, this is a test!

Comment

  1. Anonymous (NightingaleSheelagh174)
    Commented 1 month ago

    Interesting. I will follow this series.

    I see your work and content are top quality.

    1. tomgobich
      Commented 1 month ago

      Thank you!! :)

  2. meracle
    Commented 3 months ago

    Awesome episode as always. Awesome job. Looking forward to more!

    1. tomgobich
      Commented 3 months ago

      Many thanks, Dawid!! Your support is always highly appreciated!

Prepared By

Tom Gobich

Burlington, KY

Owner of Adocasts, JavaScript developer, educator, PlayStation gamer, burrito eater.

Visit Website