From a93ba30322abab9ae4a771cce6e126524f333d36 Mon Sep 17 00:00:00 2001 From: Andras Schmelczer Date: Wed, 3 Jun 2026 07:32:50 +0100 Subject: [PATCH] Add analytics --- package-lock.json | 16 +++++++++++++++- package.json | 1 + src/analytics.ts | 41 +++++++++++++++++++++++++++++++++++++++++ src/index.ts | 2 ++ 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 src/analytics.ts diff --git a/package-lock.json b/package-lock.json index 214bd85..c9d98ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "name": "sdf-2d-demo", "license": "ISC", "devDependencies": { + "@plausible-analytics/tracker": "^0.4.5", "@types/gl-matrix": "^2.4.5", "@typescript-eslint/eslint-plugin": "^3.10.1", "@typescript-eslint/parser": "^3.10.1", @@ -30,7 +31,7 @@ "resolve-url-loader": "^3.1.1", "sass": "^1.27.0", "sass-loader": "^8.0.2", - "sdf-2d": "^0.7.6", + "sdf-2d": "^0.7.4", "source-map-loader": "^1.1.1", "svg-url-loader": "^6.0.0", "ts-config-webpack-plugin": "^2.0.0", @@ -184,6 +185,13 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@plausible-analytics/tracker": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/@plausible-analytics/tracker/-/tracker-0.4.5.tgz", + "integrity": "sha512-6BfAGejXY+YA3Cw6LYT2Zpn4hTxDtPQAawFsYUsQCOg78wIS5C4deAGXTfJffa5VleMWITv5lpJ/EYuQBl1tPA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", @@ -13792,6 +13800,12 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@plausible-analytics/tracker": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/@plausible-analytics/tracker/-/tracker-0.4.5.tgz", + "integrity": "sha512-6BfAGejXY+YA3Cw6LYT2Zpn4hTxDtPQAawFsYUsQCOg78wIS5C4deAGXTfJffa5VleMWITv5lpJ/EYuQBl1tPA==", + "dev": true + }, "@types/eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", diff --git a/package.json b/package.json index 43dd77c..32145d6 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "*.scss" ], "devDependencies": { + "@plausible-analytics/tracker": "^0.4.5", "@types/gl-matrix": "^2.4.5", "@typescript-eslint/eslint-plugin": "^3.10.1", "@typescript-eslint/parser": "^3.10.1", diff --git a/src/analytics.ts b/src/analytics.ts new file mode 100644 index 0000000..9d3c5d8 --- /dev/null +++ b/src/analytics.ts @@ -0,0 +1,41 @@ +import { + init as plausibleInit, + track as plausibleTrack, + type PlausibleEventOptions, +} from '@plausible-analytics/tracker'; + +const ANALYTICS_AUTO_CAPTURE_PAGEVIEWS = true; +const ANALYTICS_DOMAIN = 'schmelczer.dev/sdf2d'; +const ANALYTICS_ENDPOINT = 'https://stats.schmelczer.dev/status'; +const ANALYTICS_LOGGING = process.env.NODE_ENV !== 'production'; + +let isInitialized = false; + +export const track = ( + eventName: string, + options: PlausibleEventOptions = {} +) => { + try { + plausibleTrack(eventName, options); + } catch (error) { + console.warn(`Could not track analytics event "${eventName}".`, error); + } +}; + +export const initAnalytics = () => { + if (isInitialized) { + return; + } + + try { + plausibleInit({ + domain: ANALYTICS_DOMAIN, + endpoint: ANALYTICS_ENDPOINT, + autoCapturePageviews: ANALYTICS_AUTO_CAPTURE_PAGEVIEWS, + logging: ANALYTICS_LOGGING, + }); + isInitialized = true; + } catch (error) { + console.warn('Could not initialize analytics.', error); + } +}; diff --git a/src/index.ts b/src/index.ts index 0012ca4..34ea7fa 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,6 +8,7 @@ import '../static/no-change/favicons/favicon-32x32.png'; import '../static/no-change/favicons/favicon.ico'; import '../static/no-change/og-image.png'; import '../static/no-change/robots.txt'; +import { initAnalytics } from './analytics'; import { extractInsights } from './helper/extract-insights'; import { handleFullScreen } from './helper/handle-full-screen'; import { handleInsights } from './helper/handle-insights'; @@ -24,6 +25,7 @@ Random.seed = 2; glMatrix.setMatrixArrayType(Array); removeUnnecessaryOutlines(); +initAnalytics(); const canvas = document.querySelector('canvas') as HTMLCanvasElement; const logo = document.querySelector('#info') as HTMLElement;