Skip to content

Commit 391a32f

Browse files
feat(page-tracker): prepend router base (#306)
closes #160
1 parent 73e6540 commit 391a32f

File tree

7 files changed

+114
-28
lines changed

7 files changed

+114
-28
lines changed

src/api/pageview.js

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getOptions } from "@/options";
2-
import { isBrowser } from "@/utils";
2+
import { getRouter } from "@/router";
3+
import { getPathWithBase, isBrowser } from "@/utils";
34
import event from "@/api/event";
45

56
export default (param) => {
@@ -14,11 +15,17 @@ export default (param) => {
1415
page_path: param,
1516
};
1617
} else if (param.path || param.fullPath) {
17-
const { pageTrackerUseFullPath } = getOptions();
18+
const {
19+
pageTrackerUseFullPath: useFullPath,
20+
pageTrackerPrependBase: useBase,
21+
} = getOptions();
22+
const router = getRouter();
23+
const base = router && router.options.base;
24+
const path = useFullPath ? param.fullPath : param.path;
1825

1926
template = {
2027
...(param.name && { page_title: param.name }),
21-
page_path: pageTrackerUseFullPath ? param.fullPath : param.path,
28+
page_path: useBase ? getPathWithBase(path, base) : path,
2229
};
2330
} else {
2431
template = param;

src/options.js

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export const getDefaultParams = () => ({
1717
pageTrackerScreenviewEnabled: false,
1818
appName: null,
1919
pageTrackerUseFullPath: false,
20+
pageTrackerPrependBase: true,
2021
pageTrackerSkipSamePath: true,
2122
globalDataLayerName: "dataLayer",
2223
globalObjectName: "gtag",

src/track.js

+14-24
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,31 @@
11
import { getOptions } from "@/options";
2-
import { warn, isFn } from "@/utils";
2+
import { validateScreenviewShape, isFn } from "@/utils";
33
import * as api from "@/api";
44

55
export default (to = {}, from = {}) => {
66
const {
77
appName,
8-
pageTrackerTemplate,
9-
pageTrackerScreenviewEnabled,
10-
pageTrackerSkipSamePath,
8+
pageTrackerTemplate: proxy,
9+
pageTrackerScreenviewEnabled: useScreenview,
10+
pageTrackerSkipSamePath: skipSamePath,
1111
} = getOptions();
1212

13-
let template = to;
14-
15-
if (isFn(pageTrackerTemplate)) {
16-
template = pageTrackerTemplate(to, from);
17-
} else if (pageTrackerScreenviewEnabled) {
18-
warn(
19-
`Missing "appName" property inside the plugin options.`,
20-
appName == null
21-
);
13+
if (skipSamePath && to.path === from.path) {
14+
return;
15+
}
2216

23-
warn(
24-
`Missing "name" property in the route with path value "${to.path}".`,
25-
to.name == null
26-
);
17+
let template = to;
2718

28-
template = {
19+
if (isFn(proxy)) {
20+
template = proxy(to, from);
21+
} else if (useScreenview) {
22+
template = validateScreenviewShape({
2923
app_name: appName,
3024
screen_name: to.name,
31-
};
32-
}
33-
34-
if (pageTrackerSkipSamePath && to.path === from.path) {
35-
return;
25+
});
3626
}
3727

38-
if (pageTrackerScreenviewEnabled) {
28+
if (useScreenview) {
3929
api.screenview(template);
4030
return;
4131
}

src/utils.js

+22
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,25 @@ export const warn = (text, shouldLog = true) => {
7878

7979
console.warn(`[vue-gtag] ${text}`);
8080
};
81+
82+
export const validateScreenviewShape = (obj = {}) => {
83+
warn(
84+
`Missing "appName" property inside the plugin options.`,
85+
obj.app_name == null
86+
);
87+
88+
warn(`Missing "name" property in the route.`, obj.screen_name == null);
89+
90+
return obj;
91+
};
92+
93+
export function getPathWithBase(path = "", base = "") {
94+
const pathAsArray = path.split("/");
95+
const baseAsArray = base.split("/");
96+
97+
if (pathAsArray[0] === "" && base[base.length - 1] === "/") {
98+
pathAsArray.shift();
99+
}
100+
101+
return baseAsArray.join("/") + pathAsArray.join("/");
102+
}

test/__snapshots__/options.spec.js.snap

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Object {
2525
"onReady": null,
2626
"pageTrackerEnabled": true,
2727
"pageTrackerExcludedRoutes": Array [],
28+
"pageTrackerPrependBase": true,
2829
"pageTrackerScreenviewEnabled": false,
2930
"pageTrackerSkipSamePath": true,
3031
"pageTrackerTemplate": null,
@@ -57,6 +58,7 @@ Object {
5758
"onReady": null,
5859
"pageTrackerEnabled": true,
5960
"pageTrackerExcludedRoutes": Array [],
61+
"pageTrackerPrependBase": true,
6062
"pageTrackerScreenviewEnabled": false,
6163
"pageTrackerSkipSamePath": true,
6264
"pageTrackerTemplate": null,

test/api/pageview.spec.js

+64
Original file line numberDiff line numberDiff line change
@@ -152,4 +152,68 @@ describe("pageview", () => {
152152
});
153153
});
154154
});
155+
156+
describe("router base path", () => {
157+
test("use with router installed", async () => {
158+
const localVue = createLocalVue();
159+
const router = new VueRouter({
160+
mode: "abstract",
161+
base: "/app/",
162+
routes: [{ path: "/" }, { path: "/about" }],
163+
});
164+
165+
localVue.use(VueRouter);
166+
localVue.use(
167+
VueGtag,
168+
{
169+
pageTrackerPrependBase: true,
170+
config: {
171+
id: 1,
172+
},
173+
},
174+
router
175+
);
176+
177+
router.push("/about");
178+
179+
await flushPromises();
180+
181+
pageview(router.currentRoute);
182+
183+
expect(event).toHaveBeenCalledWith("page_view", {
184+
send_page_view: true,
185+
page_path: "/app/about",
186+
page_location: "window_location_href_value",
187+
});
188+
});
189+
190+
test("use without router installed", async () => {
191+
const localVue = createLocalVue();
192+
const router = new VueRouter({
193+
mode: "abstract",
194+
base: "/app/",
195+
routes: [{ path: "/" }, { path: "/about" }],
196+
});
197+
198+
localVue.use(VueRouter);
199+
localVue.use(VueGtag, {
200+
pageTrackerPrependBase: true,
201+
config: {
202+
id: 1,
203+
},
204+
});
205+
206+
router.push("/about");
207+
208+
await flushPromises();
209+
210+
pageview(router.currentRoute);
211+
212+
expect(event).toHaveBeenCalledWith("page_view", {
213+
send_page_view: true,
214+
page_path: "/about",
215+
page_location: "window_location_href_value",
216+
});
217+
});
218+
});
155219
});

test/track.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ describe("track", () => {
173173
await flushPromises();
174174

175175
expect(console.warn).toHaveBeenCalledWith(
176-
`[vue-gtag] Missing "name" property in the route with path value "/about".`
176+
`[vue-gtag] Missing "name" property in the route.`
177177
);
178178
});
179179
});

0 commit comments

Comments
 (0)