Skip to content

Instantly share code, notes, and snippets.

@codebryo
Created October 12, 2018 08:15
Show Gist options
  • Save codebryo/a845beaed67e4bb79210c20ca71c48db to your computer and use it in GitHub Desktop.
Save codebryo/a845beaed67e4bb79210c20ca71c48db to your computer and use it in GitHub Desktop.
Loading Headway as Vue Widget
<template>
<div v-click-outside="hide" class="changelog">
<div class="anchor"><!-- This is a Icon we use --></div>
</div>
</template>
<script>
import uuid from 'uuid/v4'
import ClickOutside from 'vue-click-outside'
const HEADWAY_WIDGET_URL = '//cdn.headwayapp.co/widget.js'
export default {
data () {
return {
id: uuid(),
widget: undefined,
config: {
selector: '.changelog',
account: 'accountID',
callbacks: {
onWidgetReady: (widget) => { this.widget = widget },
onShowWidget: () => this.$parent.$emit('close:header-items', [this.id])
}
}
}
},
directives: {
ClickOutside
},
methods: {
hide () {
if (this.widget) this.widget.hide()
}
},
mounted () {
let headwayScript = document.createElement('script')
headwayScript.async = true
headwayScript.setAttribute('src', HEADWAY_WIDGET_URL)
document.head.appendChild(headwayScript)
const waitForHeadway = () => {
if (window['Headway']) {
window.Headway.init(this.config)
} else {
setTimeout(() => waitForHeadway(), 100)
}
}
waitForHeadway()
this.$parent.$on('close:header-items', ([id]) => {
if (this.id !== id) this.hide()
})
}
}
</script>
@maxstralin
Copy link

Thanks for sharing! Since this is the top result for "vue headway", I'd thought I'd chip in with another take, using promises.

async mounted() {
           //Inject Headway app script
           let headway = document.getElementById("headway-script");
           if (headway) return; //Script already appended

           //Create promise which resolves on script load
           let promise = new Promise((resolve, reject) => {
               let script = document.createElement("script");
               script.src = "//cdn.headwayapp.co/widget.js";
               script.id = "headway-script";
               script.setAttribute("async", true);
               document.head.appendChild(script);
               script.onload = resolve; //Resolve when loaded
               script.onerror = reject;
           });
           await promise; //Await for the script to be resolved

           //Init the widget now that the script has loaded
           // eslint-disable-next-line no-undef
           Headway.init({
               selector: ".changelog",
               account: "xxx"
           });
       },

@danbars
Copy link

danbars commented Jul 3, 2020

Thanks for posting. Few comments:

  1. import uuid from 'uuid/v4' did not work for me. I had to do import { v4 as uuid } from 'uuid'
  2. vue-click-outside was not necessary for me. headway script handles the click outside the widget without vue special handling
  3. The headway script is re-loaded every time the component is loaded. I used @maxstralin alternatives which checks if the script is loaded before loading it

@Gbahdeyboh
Copy link

I am using this example with Nuxt.

Headway initializes, and the scripts gets injected. I can also see that the headway code was added to my selector, but I can't get it to display on the page. It almost seems like it's hidden, but when I inspect the element, i can see that it is there.

@codebryo
Copy link
Author

codebryo commented Oct 8, 2021

@Gbahdeyboh maybe you need to include the Headway CSS? It requires some styles that were already loaded in my example if I recall correctly. Also I did not follow latest developments on the product so I don't know if something has changed according to their docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment