# Migration v2 to v3

All functionality from version v2 is preserved in v3, although most options have been renamed and organized by their scope. The primary focus has been on rewriting the entire codebase in TypeScript to enhance the developer experience and ensure better type safety.

In addition, new methods have been added like [consent](https://matteo-gabriele.gitbook.io/vue-gtag/methods/consent), [consentGrantedAll](https://matteo-gabriele.gitbook.io/vue-gtag/methods/consentgrantedall), [consentDeniedAll](https://matteo-gabriele.gitbook.io/vue-gtag/methods/consentdeniedall), [ecommerce](https://matteo-gabriele.gitbook.io/vue-gtag/methods/ecommerce), and the [useConsent](https://matteo-gabriele.gitbook.io/vue-gtag/gtag.js-consent-management) composable.

{% hint style="info" %}
vue-gtag is ESM-only. Check out [this](https://e18e.dev/blog/migrating-the-ecosystem-to-esm.html) article if you want to know more about the reasons behind ESM-only builds.&#x20;
{% endhint %}

### installation

v2&#x20;

```javascript
import { createApp } from "vue";
import App from "./App.vue";
import VueGtag from "vue-gtag";

createApp(App).use(VueGtag, {
  config: { id: "GA_MEASUREMENT_ID" }
}).mount("#app");
```

v3

I suggest using the \`configure\` method to install vue-gtag, as it has a smaller initial bundle size and won't add all methods to the Vue instance. While you won't be able to use $gtag in your templates, you can still import each method individually as needed.

```javascript
import { configure } from "vue-gtag";

configure({
  tagId: "GA_MEASUREMENT_ID"
})
```

Use the \`createGtag\` method if you wish to install global properties. This will increase the bundle size because all methods will be bundled together when injected into the Vue instance. You will be able to use $gtag in your template.

```javascript
import { createApp } from 'vue'
import { createGtag } from "vue-gtag";

const gtag = createGtag({
  tagId: "GA_MEASUREMENT_ID"
})

const app = createApp({ ... })
app.use(gtag)
```

{% hint style="success" %}
The installation no longer requires the App instance, and it can be triggered anywhere in your app if you don't need global events.&#x20;
{% endhint %}

{% hint style="success" %}
With v3, it is now possible to use the built-in [useConsent](https://matteo-gabriele.gitbook.io/vue-gtag/gtag.js-consent-management) composable, which will bootstrap gtag.js and provide methods to directly accept or deny user consent.
{% endhint %}

***

### Multiple account tracking

v2

```javascript
import { createApp } from "vue";
import App from "./App.vue";
import VueGtag from "vue-gtag";

createApp(App).use(VueGtag, {
  includes: [
    { id: 'GA_MEASUREMENT_ID_2' },
    { 
      id: 'GA_MEASUREMENT_ID_3',
      params: {
        anonymize_ip: true
      }
    }
  ],
  config: { id: "GA_MEASUREMENT_ID_1" }
}).mount("#app");
```

v3

```javascript
import { createGtag } from "vue-gtag";

createGtag({
  tagId: "GA_MEASUREMENT_ID",
  additionalAccounts: [
    { tagId: 'GA_MEASUREMENT_ID_2' },
    { 
      tagId: 'GA_MEASUREMENT_ID_3',
      config: {
        anonymize_ip: true
      }
    }
  ],
})
```

***

### Plugin hooks: onReady and onError

v2

```javascript
import { createApp } from "vue";
import App from "./App.vue";
import VueGtag from "vue-gtag";

createApp(App).use(VueGtag, {
  config: { id: "GA_MEASUREMENT_ID" },
  onReady: () => {},
  onError: () => {}
}).mount("#app");
```

v3

```javascript
import { createGtag } from "vue-gtag";

createGtag({
  config: { id: "GA_MEASUREMENT_ID" },
  hooks: {
    "script:loaded": () => {},
    "script:error": () => {}
  }
})

```

For more details about hooks, check the [Plugin hooks](https://matteo-gabriele.gitbook.io/vue-gtag/plugin-hooks) page

***

### Auto tracking

The auto-tracking feature moved to a separate object. Check the [Page tracker](https://matteo-gabriele.gitbook.io/vue-gtag/page-tracker) page

v2

```javascript
import { createApp } from "vue";
import VueGtag from "vue-gtag";
import App from "./App.vue";
import router from './router'
​
const app = createApp(App);
​
app.use(router);
​
app.use(VueGtag, {
  config: { 
    id: "GA_MEASUREMENT_ID",
  },
}, router); // <----- add your router here
​
app.mount("#app");
```

v3

```javascript
import { createGtag } from "vue-gtag";
import router from './router'

​createGtag({
  tagId: 'GA_MEASUREMENT_ID',
  pageTracker: {
    router, // <----- add your router here
  }
})
```

***

### Deferred plugin initialization

v2

```javascript
import { createApp } from "vue";
import VueGtag from "vue-gtag";
import App from "./App.vue";
​
const app = createApp(App);
​
app.use(VueGtag, {
  bootstrap: false,
  config: { 
    id: "GA_MEASUREMENT_ID",
  },
})
​
app.mount("#app");
```

```html
// component.vue
<script lang="ts" setup>
  import { bootstrap } from 'vue-gtag'
</script>

<template>
  <button @click="bootstrap">Add tracking</button>
</template>
```

v3

```javascript
// main.ts
import { createGtag } from "vue-gtag";
import router from './router'

​createGtag({
  tagId: 'GA_MEASUREMENT_ID',
  initMode: 'manual'
})
```

```html
// component.vue
<script lang="ts" setup>
  import { addGtag } from 'vue-gtag'
</script>

<template>
  <button @click="addGtag">Add tracking</button>
</template>
```

{% hint style="success" %}
Instead of manually calling addGtag, a more GDPR-compliant approach is to use the [useConsent](https://matteo-gabriele.gitbook.io/vue-gtag/gtag.js-consent-management) composable. This will facilitate consent handling, cookie checks, and adding gtag to your app.
{% endhint %}
