fix: queue GA4 commands in the official format
Publish GitHub Pages output / publish (push) Successful in 39s
Publish GitHub Pages output / publish (push) Successful in 39s
This commit is contained in:
+1
-1
@@ -17,7 +17,7 @@
|
|||||||
"package:offline": "npm run build:offline && powershell -NoProfile -ExecutionPolicy Bypass -File scripts/package-offline.ps1",
|
"package:offline": "npm run build:offline && powershell -NoProfile -ExecutionPolicy Bypass -File scripts/package-offline.ps1",
|
||||||
"preview": "vite preview --host 0.0.0.0",
|
"preview": "vite preview --host 0.0.0.0",
|
||||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||||
"test:engine": "node --test src/lib/engine/*.test.ts",
|
"test:engine": "node --test src/lib/engine/*.test.ts src/lib/analytics/*.test.ts",
|
||||||
"start": "node build",
|
"start": "node build",
|
||||||
"data:sync": "node scripts/collect-holodoridb.mjs",
|
"data:sync": "node scripts/collect-holodoridb.mjs",
|
||||||
"data:import-songs": "node scripts/import-legacy-song-data.mjs",
|
"data:import-songs": "node scripts/import-legacy-song-data.mjs",
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import test from 'node:test';
|
||||||
|
import { createGoogleAnalytics } from './google-analytics.ts';
|
||||||
|
|
||||||
|
test('Google 공식 형식의 arguments 객체를 dataLayer에 적재한다', () => {
|
||||||
|
const storage = new Map<string, string>();
|
||||||
|
const appendedScripts: Array<{ src?: string }> = [];
|
||||||
|
const originalWindow = globalThis.window;
|
||||||
|
const originalDocument = globalThis.document;
|
||||||
|
|
||||||
|
Object.defineProperty(globalThis, 'window', {
|
||||||
|
configurable: true,
|
||||||
|
value: {
|
||||||
|
localStorage: {
|
||||||
|
getItem: (key: string) => storage.get(key) ?? null,
|
||||||
|
setItem: (key: string, value: string) => storage.set(key, value)
|
||||||
|
},
|
||||||
|
location: { origin: 'https://doricalc-holo.live' }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(globalThis, 'document', {
|
||||||
|
configurable: true,
|
||||||
|
value: {
|
||||||
|
cookie: '',
|
||||||
|
title: '홀로도리 계산기',
|
||||||
|
createElement: () => ({ async: false, src: '', dataset: {} }),
|
||||||
|
head: { append: (script: { src?: string }) => appendedScripts.push(script) }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const analytics = createGoogleAnalytics('G-TEST1234');
|
||||||
|
analytics.grantConsent();
|
||||||
|
analytics.trackPageView('/cards');
|
||||||
|
|
||||||
|
const dataLayer = (globalThis.window as unknown as GoogleTagWindow).dataLayer ?? [];
|
||||||
|
assert.equal(dataLayer.length, 4);
|
||||||
|
assert.equal(Array.isArray(dataLayer[0]), false);
|
||||||
|
assert.equal(dataLayer[0][0], 'consent');
|
||||||
|
assert.equal(dataLayer[2][0], 'config');
|
||||||
|
assert.equal(dataLayer[3][0], 'event');
|
||||||
|
assert.equal(dataLayer[3][1], 'page_view');
|
||||||
|
assert.equal(appendedScripts[0]?.src, 'https://www.googletagmanager.com/gtag/js?id=G-TEST1234');
|
||||||
|
} finally {
|
||||||
|
Object.defineProperty(globalThis, 'window', { configurable: true, value: originalWindow });
|
||||||
|
Object.defineProperty(globalThis, 'document', { configurable: true, value: originalDocument });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
type GoogleTagWindow = Window & { dataLayer?: IArguments[] };
|
||||||
@@ -4,7 +4,7 @@ const CONSENT_STORAGE_KEY = 'holodori:analytics-consent';
|
|||||||
const MEASUREMENT_ID_PATTERN = /^G-[A-Z0-9]+$/i;
|
const MEASUREMENT_ID_PATTERN = /^G-[A-Z0-9]+$/i;
|
||||||
|
|
||||||
type GoogleTagWindow = Window & {
|
type GoogleTagWindow = Window & {
|
||||||
dataLayer?: unknown[][];
|
dataLayer?: IArguments[];
|
||||||
gtag?: (...args: unknown[]) => void;
|
gtag?: (...args: unknown[]) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -56,7 +56,9 @@ export function createGoogleAnalytics(rawMeasurementId: string | undefined): Ana
|
|||||||
if (!available || !currentWindow || loaded) return;
|
if (!available || !currentWindow || loaded) return;
|
||||||
|
|
||||||
currentWindow.dataLayer ??= [];
|
currentWindow.dataLayer ??= [];
|
||||||
currentWindow.gtag ??= (...args: unknown[]) => currentWindow.dataLayer?.push(args);
|
currentWindow.gtag ??= function googleTag(..._args: unknown[]) {
|
||||||
|
currentWindow.dataLayer?.push(arguments);
|
||||||
|
};
|
||||||
currentWindow.gtag('consent', 'default', {
|
currentWindow.gtag('consent', 'default', {
|
||||||
analytics_storage: 'granted',
|
analytics_storage: 'granted',
|
||||||
ad_storage: 'denied',
|
ad_storage: 'denied',
|
||||||
|
|||||||
Reference in New Issue
Block a user