PostHog makes it easy to get data about usage of your Vue.js app. Integrating PostHog into your app enables analytics about user behavior, custom events capture, session replays, feature flags, and more.
This guide walks you through integrating PostHog into your app for both Vue.js major versions 2
and 3
. We'll use the JavaScript SDK.
For integrating PostHog into a Nuxt.js app, see our Nuxt guide.
Prerequisites
To follow this guide along, you need:
- a PostHog account (either Cloud or self-hosted)
- a running Vue.js application
Setting up PostHog
- Install posthog-js using your package manager:
yarn add posthog-js# ornpm install --save posthog-js
Initializing PostHog
We will cover three different methods for initializing PostHog:
Choose what is best for you, considering your Vue version and your codebase’s stylistic choices.
Method 1: Create a Plugin
Note: For both Vue 3.x and Vue 2.x users
First, create a new file posthog.js
in your plugins directory.
mkdir plugins #skip if you already have onecd pluginstouch posthog.js
Next, create a plugin and assign PostHog to Vue’s global properties. The code will differ depending on your version of Vue.
Vue 3.x:
//./plugins/posthog.jsimport posthog from "posthog-js";export default {install(app) {app.config.globalProperties.$posthog = posthog.init("<ph_project_api_key>",{api_host: "<ph_instance_address>",});},};
Vue 2.x:
//./plugins/posthog.jsimport posthog from "posthog-js";export default {install(Vue, options) {Vue.prototype.$posthog = posthog.init("<ph_project_api_key>",{api_host: "<ph_instance_address>"});}};
Finally, activate your plugin in the file where you initialize your app. For Vue 3.x, it will likely be your index.js
file. For Vue 2.x, it will be your main.js
file.
Vue 3.x:
//main.jsimport { createApp } from 'vue'import App from './App.vue'import posthogPlugin from "./plugins/posthog"; //import the plugin.const app = createApp(App);app.use(posthogPlugin); //install the pluginapp.mount('#app')
Vue 2.x:
//main.jsimport posthogPlugin from "./plugins/posthog"; // import the pluginVue.use(posthogPlugin); // install the plugin, before new Vue()
You can now use PostHog throughout your Vue app using this.$posthog
. For example:
//component.vue<script>export default {data() {return {foo: "bar!",};},watch: {// whenever question changes, this function will runfoo(newFoo, oldFoo) {this.$posthog.capture("foo_changed", {foo: newFoo});},},created() {console.log("Created", this.$posthog); //posthog accessible anywhere!},};</script>
Method 2: Use provide / inject
Note: For Vue 3.x users only
With Vue 3.x, developers can use provide()
and inject()
to pipe global values into any component without prop drilling. And if you don’t know what prop drilling is, good for you.
While this method is more declarative — as you need to inject PostHog into every component — it avoids “polluting” globals (like method 1 does). Some engineers prefer this approach, while others include PostHog in globals since it doesn’t need to be reactive and will be called throughout your application.
Step 1: Initialize Vue
Prior to mounting the app, you must:
- Import PostHog
- Initialize it
- Provide it to your app.
This must be done before you mount my app. If I provide PostHog after mounting it, PostHog will not be predictably available.
//app.jsimport posthog from "posthog-js";const app = createApp(App);posthog.init("<ph_project_api_key>", {api_host: "<ph_instance_addressT>",});app.provide("posthog", posthog);
Step 2: Inject into any Vue file
//component.vueexport default {data() {return {greeting: "How are you!",};},inject: ["posthog"], //grab the injection from app-wide providercreated() {console.log("Created", this.posthog); //posthog accessible!},};
Method 3: Use Vue.prototype
Note: For Vue 2.x users only
While Vue 3.x dramatically clamped down on global variables, in Vue 2.x, you can initialize PostHog by using Object.defineProperty
and Vue.prototype
.
Anywhere, declare:
import posthog from "posthog-js";Object.defineProperty(Vue.prototype, '$posthog', { value: posthog });
Then, access PostHog by calling this.$posthog
.
//component.vueexport default {created() {this.$posthog.capture("app_created");}}
Capturing page views
While PostHog will automatically capture paths, you can optionally bind it to Vue’s built-in router using the afterEach
function. Additionally, you can mount PostHog inside nextTick
so that the capture event fires after the page is mounted.
Vue 3.x:
//router.js #might be in your app.jsrouter.afterEach((to) => {nextTick(() => {posthog.capture("$pageview", {$current_url: to.fullPath,});});});
Vue 2.x:
export default new Router({/****/afterEach: to => {nextTick(() => {posthog.capture("$pageview", {$current_url: to.fullPath});});}});
Capturing events
Here’s a simple example of using PostHog to capture a barebones login button.
//component.vue<script>export default {data(props) {return {user: props.user,};},created() {console.log("Created", this.$posthog); //posthog accessible anywhere!},methods: {login() {this.$posthog.capture("User logged in");//should be this.posthog if you used method 2!}}};</script><template><button @click="login">Login!</button></template>
See the JavaScript SDK docs for all usable functions, such as:
- Capture custom event capture, identify users, and more.
- Feature flags including variants and payloads.
You can the access the project used in this tutorial on GitHub.