Inertia: Inertia emitted events

Created on 25 Aug 2019  路  20Comments  路  Source: inertiajs/inertia

More of a question, than an issue per se...

A couple of previous apps I've worked on have used turbolinks and vue - pretty much as @reinink described in his article about backend apps with client rendering

What's useful about using turbolinks in this approach, is that it emits a heap of events, that your application can hook in to - for example - fire off analytics tracking, etc.

I think there might be merit for inertia.js to emit some of its own events for other parts of applications to latch on to.

For example, you could listen for events like click, visit, hardvisit, restore, under an inertia namespace:

document.addEventListener('inertia:visit', (event) => {
    // do something, for example: 
    dataLayer.push({
      'url': event.data.path, // e.g. `/user/1/update`
      'event': event.data.trigger // e.g `updateProfile`
    });
});

If this is something that folks would find useful, I might be able to hack on a PR to add such a feature.

Any thoughts?

Most helpful comment

@Stian-Scholtz Coming soon: #208 馃槈

All 20 comments

@theblindfrog This seems like cool feature indeed!

We should wait for feedback from @reinink and @sebastiandedeyne on this, but I don't see any reason why this wouldn't be good feature for the framework. 馃槃

I like this idea, maybe we could even use it internally to deal with the loading indicator (it would also provide a way for users to implement custom loading indicators)

@sebastiandedeyne That's an _even better_ use-case for something like this.

After more thought, what I'm trying to do could be achieved in the 'layout' layer of my app (or most apps, fwiw) - firing off a new pageview to analytics as new frontend component(s) are created.

Depending on what @reinink's view is, the original thrust of this issue might not be relevant; even if the 'loading indicator' use-case may warrant another look.

So, events are certainly on my radar. However, I can't decide if they offer any real benefit over simply providing additional configuration options, either at the adapter level, or even with Inertia core.

Fair point @reinink. Perhaps they're the 'easy' way to offer some of this functionality; in contrast to more elegant implementations.

I'll close this issue. Thanks!

Thanks for posting either way! We'll be dealing with this at some point as we near 1.0.

Did any of this make it into v.1? I'm having some difficulties figuring out how to fire my analytics events. Any existing strategies you guys know of that would work with Inertia?

AFAIK emitted events have not made it into inertia.. but I solved this by adding my analytics/tracking code to the 'Layout' view (vue, jsx, etc) of inertia.

So for vue, you could do something like

<template>
// your layout
</template>

<script>

export default {

  props: {
    url: String,
  },

  mounted() {

    // Google Analytics via GTM
    dataLayer.push({
        'event': 'pageView',
        'virtualUrl': this.$inertia.page.url;,
    });

  }
}
</script>

Hope that helps @ellefsen

Thanks. That does work for now. I figured it wouldn't because Vue wouldn't re-render the layout component on each page request, but it does so for now that's how I'll roll.

Thanks @theblindfrog !

Ha! I had those same thoughts initially too.
PingCRM used to (now uses a plugin) update the document title in a similar way.

...
  watch: {
    title: {
      immediate: true,
      handler(title) {
        document.title = title ? `${title} | Ping CRM` : 'Ping CRM'
      },
    },
  },
...

Code: https://github.com/inertiajs/pingcrm/blob/424aeff32218983c01f0f7617887b224e7c93117/resources/js/Shared/Layout.vue#L74-L81

Recently I noticed that transformProps can be used as event hook. It is executed on every response received by Inertia.

Example usage here:
https://github.com/ledermann/pingcrm/blob/638bdd82a0a64a7462555215ebfff71c3472a827/app/javascript/packs/application.js#L51-L63

Nice find @ledermann!

Reopening, as this is something we still need to deal with. 馃憤

I haven't needed events with Inertia myself but I see it could be very useful. What about extending the Inertia object with mitt? The API for subscribing to Inertia events would look like:

Inertia.on('click', event => /* ... */)
Inertia.on('visit', url => /* ... */)

For example Turbolinks uses the default DOM event listeners. From the docs:

Turbolinks emits events that allow you to track the navigation lifecycle and respond to page loading. Except where noted, Turbolinks fires events on the document object.

Maybe this can be used in Inertia aswell. So dispatching events are as simple as:

    const event = new Event('inertia:visit')
    document.dispatchEvent(event)

Everyone can listen to events like this:

    document.addEventListener('inertia:visit', () => alert('visit'))

This is a solution that relies heavily on the DOM though.

Another solution might be using an event emitter like https://github.com/component/emitter/.

@reinink What is your preference?

Adding my interest to this. We have been using some very 'hacky' solutions to update a complex navigation structure. Hooking into an event in the navigation component to listen for an inertia page load would be much more elegant.

Adding my interest as well. Need it to update navigation as well and to log every click to a database.

I haven't needed events with Inertia myself but I see it could be very useful. What about extending the Inertia object with mitt? The API for subscribing to Inertia events would look like:

Inertia.on('click', event => /* ... */)
Inertia.on('visit', url => /* ... */)

This would be very useful. One case I would like to use it is when I want to display a custom loading indicator. I.e. when inertia emits a loading event I can display my loader accordingly.

@Stian-Scholtz Coming soon: #208 馃槈

The new event system (#208) has been merged in. I hope to tag a release tomorrow, and I also plan to add documentation to the website explaining how to use it. 馃檶

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gajosadrian picture gajosadrian  路  5Comments

sebastiandedeyne picture sebastiandedeyne  路  6Comments

philippkuehn picture philippkuehn  路  3Comments

jalt007 picture jalt007  路  4Comments

kufdaw picture kufdaw  路  6Comments