🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Book a DemoInstallSign in
Socket

vue-gtm

Package Overview
Dependencies
Maintainers
2
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vue-gtm - npm Package Compare versions

Comparing version

to
3.5.0-vue2

15

CHANGELOG.md
# Next
[diff](https://github.com/mib200/vue-gtm/compare/3.4.1...master)
[diff](https://github.com/mib200/vue-gtm/compare/3.5.0...master)
# 3.5.0
[diff](https://github.com/mib200/vue-gtm/compare/3.4.1...3.5.0)
- Add `nonce` for CSP support ([#116])
**Vue 3 only**
- Handle optional dependency of `vue-router` ([#122])
[#116]: https://github.com/mib200/vue-gtm/issues/116
[#122]: https://github.com/mib200/vue-gtm/issues/122
# 3.4.1

@@ -6,0 +19,0 @@

@@ -1,2 +0,2 @@

import type { Router } from "vue-router";
import type Router from "vue-router";
/**

@@ -80,2 +80,8 @@ * Query parameter object that will be send to GTM.

/**
* Will add `nonce` to the script tag.
*
* @see [Using Google Tag Manager with a Content Security Policy](https://developers.google.com/tag-manager/web/csp)
*/
nonce?: string;
/**
* Plugin can be disabled by setting this to `false`.

@@ -82,0 +88,0 @@ *

21

dist/index.d.ts

@@ -1,13 +0,6 @@

import { Plugin } from "vue";
import { PluginObject } from "vue";
import { VueGtmUseOptions } from "./config";
import GtmPlugin from "./plugin";
/**
* Create the Vue GTM instance.
*
* @param options Options.
* @returns The Vue GTM plugin instance.
*/
export declare function createGtm(options: VueGtmUseOptions): VueGtmPlugin;
declare module "@vue/runtime-core" {
interface ComponentCustomProperties {
declare module "vue/types/vue" {
interface Vue {
/**

@@ -18,2 +11,8 @@ * The Vue GTM Plugin instance.

}
interface VueConstructor<V extends Vue = Vue> {
/**
* The Vue GTM Plugin instance.
*/
gtm: GtmPlugin;
}
}

@@ -23,3 +22,3 @@ /**

*/
export declare type VueGtmPlugin = Plugin;
export declare type VueGtmPlugin = PluginObject<VueGtmUseOptions>;
export { VueGtmUseOptions } from "./config";

@@ -26,0 +25,0 @@ declare const _default: VueGtmPlugin;

@@ -13,38 +13,2 @@ "use strict";

};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __values = (this && this.__values) || function(o) {

@@ -62,4 +26,3 @@ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;

Object.defineProperty(exports, "__esModule", { value: true });
exports.useGtm = exports.createGtm = void 0;
var vue_1 = require("vue");
exports.useGtm = void 0;
var config_1 = require("./config");

@@ -85,6 +48,6 @@ var plugin_1 = require("./plugin");

*
* @param app The Vue app instance.
* @param Vue The Vue instance.
* @param options Configuration options.
*/
function install(app, options) {
function install(Vue, options) {
var e_1, _a;

@@ -119,6 +82,6 @@ if (options === void 0) { options = { id: "" }; }

gtmPlugin = new plugin_1.default(options.id, options);
app.config.globalProperties.$gtm = gtmPlugin;
Vue.prototype.$gtm = Vue.gtm = gtmPlugin;
// Handle vue-router if defined
if (options.vueRouter) {
void initVueRouterGuard(app, options.vueRouter, options.ignoredViews, options.trackOnNextTick);
initVueRouterGuard(Vue, options.vueRouter, options.ignoredViews, options.trackOnNextTick);
}

@@ -145,3 +108,2 @@ // Load GTM script when enabled

}
app.provide("gtm", options);
}

@@ -151,3 +113,3 @@ /**

*
* @param app The Vue app instance.
* @param Vue The Vue instance.
* @param vueRouter The Vue router instance to attach the guard.

@@ -157,70 +119,35 @@ * @param ignoredViews An array of route name that will be ignored.

*/
function initVueRouterGuard(app, vueRouter, ignoredViews, trackOnNextTick) {
function initVueRouterGuard(Vue, vueRouter, ignoredViews, trackOnNextTick) {
if (ignoredViews === void 0) { ignoredViews = []; }
return __awaiter(this, void 0, void 0, function () {
var vueRouterModule, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 2, , 3]);
return [4 /*yield*/, Promise.resolve().then(function () { return require("vue-router"); })];
case 1:
vueRouterModule = _b.sent();
return [3 /*break*/, 3];
case 2:
_a = _b.sent();
console.warn("[VueGtm]: You tried to register 'vueRouter' for vue-gtm, but 'vue-router' was not found.");
return [2 /*return*/];
case 3:
// Flatten routes name
ignoredViews = ignoredViews.map(function (view) { return view.toLowerCase(); });
vueRouter.afterEach(function (to, from, failure) {
var _a, _b, _c, _d, _e;
// Ignore some routes
if (typeof to.name !== "string" || ignoredViews.indexOf(to.name.toLowerCase()) !== -1) {
return;
}
// Dispatch vue event using meta gtm value if defined otherwise fallback to route name
var name = to.meta && typeof to.meta.gtm === "string" && !!to.meta.gtm ? to.meta.gtm : to.name;
if (vueRouterModule.isNavigationFailure(failure, vueRouterModule.NavigationFailureType.aborted)) {
if (gtmPlugin === null || gtmPlugin === void 0 ? void 0 : gtmPlugin.debugEnabled()) {
console.log("[VueGtm]: '" + name + "' not tracked due to navigation aborted");
}
}
else if (vueRouterModule.isNavigationFailure(failure, vueRouterModule.NavigationFailureType.cancelled)) {
if (gtmPlugin === null || gtmPlugin === void 0 ? void 0 : gtmPlugin.debugEnabled()) {
console.log("[VueGtm]: '" + name + "' not tracked due to navigation cancelled");
}
}
var additionalEventData = (_b = (_a = to.meta) === null || _a === void 0 ? void 0 : _a.gtmAdditionalEventData) !== null && _b !== void 0 ? _b : {};
var baseUrl = (_e = (_d = (_c = vueRouter.options) === null || _c === void 0 ? void 0 : _c.history) === null || _d === void 0 ? void 0 : _d.base) !== null && _e !== void 0 ? _e : "";
var fullUrl = baseUrl;
if (!fullUrl.endsWith("/")) {
fullUrl += "/";
}
fullUrl += to.fullPath.startsWith("/") ? to.fullPath.substr(1) : to.fullPath;
if (trackOnNextTick) {
void vue_1.nextTick(function () {
gtmPlugin === null || gtmPlugin === void 0 ? void 0 : gtmPlugin.trackView(name, fullUrl, additionalEventData);
});
}
else {
gtmPlugin === null || gtmPlugin === void 0 ? void 0 : gtmPlugin.trackView(name, fullUrl, additionalEventData);
}
});
return [2 /*return*/];
}
});
if (!vueRouter) {
console.warn("[VueGtm]: You tried to register 'vueRouter' for vue-gtm, but 'vue-router' was not found.");
return;
}
// Flatten routes name
ignoredViews = ignoredViews.map(function (view) { return view.toLowerCase(); });
vueRouter.afterEach(function (to) {
var _a, _b, _c;
// Ignore some routes
if (typeof to.name !== "string" || ignoredViews.indexOf(to.name.toLowerCase()) !== -1) {
return;
}
// Dispatch vue event using meta gtm value if defined otherwise fallback to route name
var name = to.meta && typeof to.meta.gtm === "string" && !!to.meta.gtm ? to.meta.gtm : to.name;
var additionalEventData = (_b = (_a = to.meta) === null || _a === void 0 ? void 0 : _a.gtmAdditionalEventData) !== null && _b !== void 0 ? _b : {};
var baseUrl = (_c = vueRouter.options.base) !== null && _c !== void 0 ? _c : "";
var fullUrl = baseUrl;
if (!fullUrl.endsWith("/")) {
fullUrl += "/";
}
fullUrl += to.fullPath.startsWith("/") ? to.fullPath.substr(1) : to.fullPath;
if (trackOnNextTick) {
Vue.nextTick(function () {
gtmPlugin === null || gtmPlugin === void 0 ? void 0 : gtmPlugin.trackView(name, fullUrl, additionalEventData);
});
}
else {
gtmPlugin === null || gtmPlugin === void 0 ? void 0 : gtmPlugin.trackView(name, fullUrl, additionalEventData);
}
});
}
/**
* Create the Vue GTM instance.
*
* @param options Options.
* @returns The Vue GTM plugin instance.
*/
function createGtm(options) {
return { install: function (app) { return install(app, options); } };
}
exports.createGtm = createGtm;
var _default = { install: install };

@@ -227,0 +154,0 @@ exports.default = _default;

@@ -9,3 +9,3 @@ import "url-search-params-polyfill";

*/
export declare function loadScript(id: string, config?: Pick<VueGtmUseOptions, "defer" | "compatibility" | "queryParams">): void;
export declare function loadScript(id: string, config?: Pick<VueGtmUseOptions, "defer" | "compatibility" | "nonce" | "queryParams">): void;
/**

@@ -12,0 +12,0 @@ * Check if GTM script is in the document.

@@ -38,2 +38,5 @@ "use strict";

script.defer = Boolean(config.defer || config.compatibility);
if (config.nonce) {
script.nonce = config.nonce;
}
var queryString = new URLSearchParams(__assign({ id: id }, ((_c = config.queryParams) !== null && _c !== void 0 ? _c : {})));

@@ -40,0 +43,0 @@ script.src = "https://www.googletagmanager.com/gtm.js?" + queryString;

{
"name": "vue-gtm",
"version": "3.4.2-issue-122.1",
"version": "3.5.0-vue2",
"description": "Google Tag Manager implementation in Vue application",

@@ -62,8 +62,8 @@ "main": "dist/index.js",

"devDependencies": {
"@types/jest": "~26.0.20",
"@typescript-eslint/eslint-plugin": "~4.17.0",
"@typescript-eslint/parser": "~4.17.0",
"eslint": "~7.21.0",
"@types/jest": "~26.0.21",
"@typescript-eslint/eslint-plugin": "~4.19.0",
"@typescript-eslint/parser": "~4.19.0",
"eslint": "~7.22.0",
"eslint-config-prettier": "~8.1.0",
"eslint-plugin-jsdoc": "~32.2.0",
"eslint-plugin-jsdoc": "~32.3.0",
"eslint-plugin-prettier": "~3.3.1",

@@ -75,13 +75,10 @@ "eslint-plugin-spellcheck": "~0.0.17",

"prettier-plugin-organize-imports": "~1.1.1",
"ts-jest": "~26.5.3",
"ts-jest": "~26.5.4",
"typescript": "~4.2.3",
"vue": "^3.0.0",
"vue-router": "^4.0.0"
"vue": "^2.6.12",
"vue-router": "^3.5.1"
},
"peerDependencies": {
"vue": "^3.0.0"
},
"optionalDependencies": {
"vue-router": "^4.0.0"
"vue": "^2.6.0"
}
}

@@ -78,2 +78,3 @@ <h1 align="center">Vue Google Tag Manager</h1>

compatibility: false, // Will add `async` and `defer` to the script tag to not block requests for old browsers that do not support `async`
nonce: "2726c7f26c", // Will add `nonce` to the script tag
enabled: true, // defaults to true. Plugin can be disabled by setting this to false for Ex: enabled: !!GDPR_Cookie (optional)

@@ -80,0 +81,0 @@ debug: true, // Whether or not display console logs debugs (optional)

@@ -1,2 +0,2 @@

import type { Router } from "vue-router";
import type Router from "vue-router";

@@ -84,2 +84,8 @@ /**

/**
* Will add `nonce` to the script tag.
*
* @see [Using Google Tag Manager with a Content Security Policy](https://developers.google.com/tag-manager/web/csp)
*/
nonce?: string;
/**
* Plugin can be disabled by setting this to `false`.

@@ -86,0 +92,0 @@ *

@@ -1,2 +0,2 @@

import { App, nextTick, Plugin } from "vue";
import _Vue, { PluginObject } from "vue";
import { DEFAULT_CONFIG, VueGtmContainer, VueGtmQueryParams, VueGtmUseOptions } from "./config";

@@ -25,6 +25,6 @@ import GtmPlugin from "./plugin";

*
* @param app The Vue app instance.
* @param Vue The Vue instance.
* @param options Configuration options.
*/
function install(app: App, options: VueGtmUseOptions = { id: "" }): void {
function install(Vue: typeof _Vue, options: VueGtmUseOptions = { id: "" }): void {
if (Array.isArray(options.id)) {

@@ -47,7 +47,7 @@ for (const idOrObject of options.id) {

gtmPlugin = new GtmPlugin(options.id, options);
app.config.globalProperties.$gtm = gtmPlugin;
Vue.prototype.$gtm = Vue.gtm = gtmPlugin;
// Handle vue-router if defined
if (options.vueRouter) {
void initVueRouterGuard(app, options.vueRouter, options.ignoredViews, options.trackOnNextTick);
initVueRouterGuard(Vue, options.vueRouter, options.ignoredViews, options.trackOnNextTick);
}

@@ -80,4 +80,2 @@

}
app.provide("gtm", options);
}

@@ -88,3 +86,3 @@

*
* @param app The Vue app instance.
* @param Vue The Vue instance.
* @param vueRouter The Vue router instance to attach the guard.

@@ -94,12 +92,9 @@ * @param ignoredViews An array of route name that will be ignored.

*/
async function initVueRouterGuard(
app: App,
function initVueRouterGuard(
Vue: typeof _Vue,
vueRouter: Exclude<VueGtmUseOptions["vueRouter"], undefined>,
ignoredViews: VueGtmUseOptions["ignoredViews"] = [],
trackOnNextTick: VueGtmUseOptions["trackOnNextTick"]
): Promise<void> {
let vueRouterModule: typeof import("vue-router");
try {
vueRouterModule = await import("vue-router");
} catch {
): void {
if (!vueRouter) {
console.warn("[VueGtm]: You tried to register 'vueRouter' for vue-gtm, but 'vue-router' was not found.");

@@ -112,3 +107,3 @@ return;

vueRouter.afterEach((to, from, failure) => {
vueRouter.afterEach((to) => {
// Ignore some routes

@@ -121,15 +116,4 @@ if (typeof to.name !== "string" || ignoredViews.indexOf(to.name.toLowerCase()) !== -1) {

const name: string = to.meta && typeof to.meta.gtm === "string" && !!to.meta.gtm ? to.meta.gtm : to.name;
if (vueRouterModule.isNavigationFailure(failure, vueRouterModule.NavigationFailureType.aborted)) {
if (gtmPlugin?.debugEnabled()) {
console.log(`[VueGtm]: '${name}' not tracked due to navigation aborted`);
}
} else if (vueRouterModule.isNavigationFailure(failure, vueRouterModule.NavigationFailureType.cancelled)) {
if (gtmPlugin?.debugEnabled()) {
console.log(`[VueGtm]: '${name}' not tracked due to navigation cancelled`);
}
}
const additionalEventData: Record<string, any> = (to.meta?.gtmAdditionalEventData as Record<string, any>) ?? {};
const baseUrl: string = vueRouter.options?.history?.base ?? "";
const additionalEventData: Record<string, any> = to.meta?.gtmAdditionalEventData ?? {};
const baseUrl: string = vueRouter.options.base ?? "";
let fullUrl: string = baseUrl;

@@ -142,3 +126,3 @@ if (!fullUrl.endsWith("/")) {

if (trackOnNextTick) {
void nextTick(() => {
Vue.nextTick(() => {
gtmPlugin?.trackView(name, fullUrl, additionalEventData);

@@ -152,15 +136,5 @@ });

/**
* Create the Vue GTM instance.
*
* @param options Options.
* @returns The Vue GTM plugin instance.
*/
export function createGtm(options: VueGtmUseOptions): VueGtmPlugin {
return { install: (app: App) => install(app, options) };
}
declare module "@vue/runtime-core" {
declare module "vue/types/vue" {
// eslint-disable-next-line jsdoc/require-jsdoc
export interface ComponentCustomProperties {
export interface Vue {
/**

@@ -171,2 +145,9 @@ * The Vue GTM Plugin instance.

}
// eslint-disable-next-line jsdoc/require-jsdoc
export interface VueConstructor<V extends Vue = Vue> {
/**
* The Vue GTM Plugin instance.
*/
gtm: GtmPlugin;
}
}

@@ -177,3 +158,3 @@

*/
export type VueGtmPlugin = Plugin;
export type VueGtmPlugin = PluginObject<VueGtmUseOptions>;
export { VueGtmUseOptions } from "./config";

@@ -180,0 +161,0 @@

@@ -12,3 +12,3 @@ import "url-search-params-polyfill";

id: string,
config: Pick<VueGtmUseOptions, "defer" | "compatibility" | "queryParams"> = {}
config: Pick<VueGtmUseOptions, "defer" | "compatibility" | "nonce" | "queryParams"> = {}
): void {

@@ -33,2 +33,6 @@ const doc: Document = document;

if (config.nonce) {
script.nonce = config.nonce;
}
const queryString: URLSearchParams = new URLSearchParams({

@@ -35,0 +39,0 @@ id,