How To Add InertiaJS to a New AdonisJS Project

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

Published
Jun 05, 22
Duration
8m 55s

Developer, dog lover, and burrito eater. Currently teaching AdonisJS, a fully featured NodeJS framework, and running Adocasts where I post new lessons weekly. Professionally, I work with JavaScript, .Net C#, and SQL Server.

Adocasts

Burlington, KY

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
Copied!

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

cd adonis-inertia-example
Copied!

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
Copied!

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
Copied!

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
Copied!

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
})
Copied!

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.

//start/kernel.ts

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

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.

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

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

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>
Copied!
  • resources
  • js
  • Pages
  • Home.vue

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) })
Copied!

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.

Route.get('/home', async ({ inertia }) => {
  return inertia.render('Home')
})
Copied!
  • start
  • routes.ts

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.

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

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>
Copied!
  • resources
  • js
  • Pages
  • Home.vue

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

Join The Discussion! (14 Comments)

Please sign in or sign up for free to join in on the dicussion.

  1. Commented 1 year ago

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

    2

    Please sign in or sign up for free to reply

    1. Commented 1 year ago

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

      0

      Please sign in or sign up for free to reply

  2. Anonymous (NightingaleSheelagh174)
    Commented 1 year ago

    Interesting. I will follow this series.

    I see your work and content are top quality.

    1

    Please sign in or sign up for free to reply

    1. Commented 1 year ago

      Thank you!! :)

      0

      Please sign in or sign up for free to reply

  3. Anonymous (BoaAngelle330)
    Commented 1 year ago

    Awesome stuff, helped me get setup using React!

    Dropping a comment for those who want to do this using react, put together a rough guide here: https://github.com/kevinchar93/csr-adonis-inertia-react

    Love your other content too, looking forward to more Lucid videos :)

    1

    Please sign in or sign up for free to reply

    1. Commented 1 year ago

      Thank you!

      And, thanks for putting together and sharing your React guide! :)

      0

      Please sign in or sign up for free to reply

  4. Commented 1 year ago

    Hi. After installing inertia I have this warning in my browser :

    Feature flags __VUE_OPTIONS_API__, __VUE_PROD_DEVTOOLS__ are not explicitly defined.

    Do you know why and how to solve it ? After searching for a while I can't find a solution.

    1

    Please sign in or sign up for free to reply

    1. Commented 1 year ago

      Hi Jean! You should be able to toggle those on/off within Webpack Encore similar to what's being done in this linked code snippet.

      Encore.enableVueLoader(() => {}, {
        version: 3,
        runtimeCompilerBuild: false,
        useJsx: false
      }).enableTypeScriptLoader(config => {
        config.configFile = 'tsconfig.vue.json'
      }).addAliases({
        '@': join(__dirname, 'resources/js')
      }).configureDefinePlugin(options => {
        options['__VUE_OPTIONS_API__'] = true
        options['__VUE_PROD_DEVTOOLS__'] = false
      })
      1

      Please sign in or sign up for free to reply

      1. Commented 1 year ago

        THANKS.

        0

        Please sign in or sign up for free to reply

        1. Commented 1 year ago

          Anytime!

          0

          Please sign in or sign up for free to reply

  5. Commented 3 months ago

    Hi, One small update required: In your app.js the vue 3 inertia package is no longer @inertiajs/inertia-vue3 it's been updated to @inertiajs/vue3

    1

    Please sign in or sign up for free to reply

    1. Commented 3 months ago

      Thank you for the heads up there, Dylan!!

      0

      Please sign in or sign up for free to reply

  6. Commented 1 month ago

    I love how you say Laravel is "kinda similar" to Adonis. That made me laugh. I came to Adonis from Laravel, and it feels like a port of Laravel to Node.JS. :)

    1

    Please sign in or sign up for free to reply

    1. Commented 1 month ago

      Yeah lol! The core team definitely used Laravel as inspiration to shape the foundations of AdonisJS! I came from Laravel as well, JavaScript has always been my primary language so I was super happy when I learned about it 😄

      0

      Please sign in or sign up for free to reply