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

Understanding The Flow Between Adonis, Inertia, and Vue 3

06:59 Watch
4:17 Read

In this lesson, we'll be inspecting the request flow from Adonis through Inertia and to Vue for both initial and subsequent requests.

Watch on YouTube
GitHub
View Repository

Before we delve too deeply into using InertiaJS it’s important to understand the flow that’s happening when a request is made. So, let’s take a moment to understand where AdonisJS ends, where InertiaJS takes over, and what’s passed along to VueJS.

Remember our Vue application is a single-page application (SPA).

The Inertia Render

First let’s tackle the question, “what is inertia.render doing?” The answer to this question is two-fold depending on whether it’s handling an initial request or subsequent page requests.

The Initial Request

When we make our first page request into our Vue SPA, the inertia.render call will include our application’s Edge file, which looks like the below.

{{-- 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>adonis-inertia-example</title>
</head>
<body>
  @inertia()
</body>
</html>

If you’re familiar with Edge, the only thing unfamiliar with the above should be @inertia(). In essence, this Edge component is dropping the markup for our Vue application on the page. It doesn’t initialize anything with Vue, it merely drops the div element that will house our Vue app.

<div id="app" data-page="{ "component": "Home", props: { "testing": "This is a test" }, ... }"></div>

The data-page attribute contains information for the initial state of our Vue app.

  • Component: The initial page component to display

  • Props: Data provided to inertia.render which will be passed to our page component as props.

  • Url: The current route’s url

  • Version: The current version for our application, this comes from our manifest file.

So, in essence, for initial requests, inertia.render will return back the following HTML as it’s response:

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

  <link rel="stylesheet" href="<http://localhost:8080/assets/app.css>">
  <script src="<http://localhost:8080/assets/app.js>" defer=""></script>

  <title>adonis-inertia-example</title>
</head>
<body>
  <div id="app" data-page="{ "component": "Home", props: { "testing": "This is a test" }, ... }"></div>
</body>
</html>

In terms of rendering, this is all that’s done on the server-side. Our Vue application isn’t actually instantiated until our app.js script is loaded in and our createApp is called.

// resources/js/app.js

import '../css/app.css'
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)
  },
})

After our Vue application is instantiated everything else, including traveling to other pages is all done on the client-side; apart from grabbing information from Adonis for our routes.

Client-Side Routing

Inertia serves as our client-side router. Similar to Vue Router, Inertia will wrap our application with an inertia component. This component allows us to easily change pages within our Vue app without needing to re-instantiate our Vue app.

It works in tandem with a special Link component. In order to traverse from one page to another, we must use this Link component. Otherwise, the page change will be treated as an initial request and our Vue app will need to be re-instantiated, wasting time and resources for our users.

When we visit another page using this Link component, the component will kick off a GET request to Adonis for the desired route. This is where we meet inertia.render once more, this time for a subsequent request. It’ll pick up on this using content negotiation and instead of returning back HTML markup will return back a JSON response containing the same information provided within the data-page attribute on our initial request.

{
  "component":"Home",
  "version":"e77ee25438e9f73dc55c00b5e3ee4e15",
  "props": { "testing": "This is a test" },
  "url":"/1/dashboard"
}

Inertia’s Link component is rather powerful. In this lesson, we’re merely going to take a look at how to use it to get from one page to another. In this section, we’ll be making a login page to serve as our second page.

First, though, let’s learn how to use the Link component on our home page.

<template>
  <div>
    <link href="/login">Login</link> <!-- 👈 use it -->
    <h1>Testing, {{ testing }}</h1>
  </div>
</template>

<script>
  import { Link } from '@inertiajs/inertia-vue3'. // 👈 import it

  export default {
    props: {
      testing: String
    },

    components: {
      Link // 👈 define it
    }
  }
</script>
  1. First, import it from @inertiajs/inertia-vue3.

  2. Next, define it as a component, when necessary.

  3. Lastly, use it! Note that href is used to specify the path to go to.

Login Page

Next, let’s add our login page so we have an actual page to link to. First, let’s define the route in Adonis.

// start/routes.ts

Route.get('/login', async ({ inertia }) => {
  return inertia.render('Auth/Login')
})

We’ll be putting our authentication-specific pages inside an Auth folder. So, let’s create our page component at resources/js/Pages/Auth/Login.vue.

<template>
  <div>
    <link href="/home">Go Home</link>
    <h1>Login</h1>
  </div>
</template>

<script setup>
  import { Link } from '@inertiajs/inertia-vue3'
</script>

Note that since we’re using a setup script here, we don’t need to define the component as we did on our home page.

Testing It Out

With that in place, you should be good to go ahead and test it out! Boot up your server with npm run dev and click between the home and login pages. You should notice within your developer tool’s inspector that after the initial request, the HTML structure remains the same and only the application’s contents are swapped out.

Additionally, if you inspect the Network tab, you should see a GET request go off every time you swap between pages to capture information for that specific page.

Comment

Prepared By

Tom Gobich

Burlington, KY

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

Visit Website