Vue Turbolinks Hotwire Adapter

2.2.2 · active · verified Sun Apr 19

vue-turbolinks is a JavaScript package designed to facilitate the integration of Vue.js components into applications that utilize Turbolinks or Hotwire's Turbo. Its primary function is to manage the lifecycle events of Vue components—specifically their proper setup and teardown—within the context of a Turbolinks/Turbo page navigation cycle. This allows developers to incrementally add interactive Vue elements to traditional server-rendered applications without converting them into full Single-Page Applications (SPAs). The current stable version is 2.2.2, with recent minor updates indicating active maintenance. A key differentiator is its explicit focus on solving the challenges of combining Vue's reactivity with Turbolinks'/Turbo's caching mechanisms, making it unsuitable and unnecessary for projects already employing client-side routing libraries like Vue Router.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to initialize a Vue component using the `turbolinksAdapterMixin` on a `turbo:load` event, ensuring proper lifecycle management with Hotwire/Turbolinks. It includes a basic Vue component and simulates the DOM changes and events typical in a Turbo application.

import { turbolinksAdapterMixin } from 'vue-turbolinks';
import Vue from 'vue';

// A mock App component for demonstration
const App = {
  template: '<div>Hello from Vue and Turbolinks! Count: {{ count }} <button @click="count++">Increment</button></div>',
  data() {
    return { count: 0 };
  },
  mounted() {
    console.log('App mounted!');
  },
  beforeDestroy() {
    console.log('App beforeDestroy!');
  }
};

document.addEventListener('turbo:load', () => {
  const element = document.getElementById("hello");

  if (element != null) {
    new Vue({
      el: element,
      template: '<App/>',
      mixins: [turbolinksAdapterMixin],
      components: { App }
    });
    console.log('Vue app initialized on turbo:load.');
  } else {
    console.log('No #hello element found, skipping Vue initialization.');
  }
});

// Simulate a Turbolinks/Turbo page load for demonstration
// In a real app, this would be triggered by navigation.
setTimeout(() => {
  const rootDiv = document.createElement('div');
  rootDiv.id = 'hello';
  document.body.appendChild(rootDiv);
  document.dispatchEvent(new Event('turbo:load'));
}, 500);

setTimeout(() => {
  const elementToRemove = document.getElementById('hello');
  if (elementToRemove) {
    elementToRemove.parentNode.removeChild(elementToRemove);
  }
  document.dispatchEvent(new Event('turbo:before-cache')); // Simulate cache event
}, 3000);

view raw JSON →