diff --git a/.env.development b/.env.development
index 97311c006..e55f9fdf1 100644
--- a/.env.development
+++ b/.env.development
@@ -92,6 +92,29 @@ STRIPE_CREDITS_1000_PRICE=price_1T1OkNAZjQCYS0ZJvc6HTfB5
# Customer Portal Configuration
STRIPE_PORTAL_CONFIG_ID=bpc_1T1PFdAZjQCYS0ZJEhF9ob7q
+# ============================================
+# UMAMI ANALYTICS - Website IDs per app
+# ============================================
+# These are the Umami website IDs for each web app.
+# Register new apps at https://umami.mana.how
+UMAMI_WEBSITE_ID_CHAT=1c43fd98-4767-4f89-9dc2-ebdfbd8960db
+UMAMI_WEBSITE_ID_MANACORE=face76f4-2d3e-42be-b8c8-0ea03f33a462
+UMAMI_WEBSITE_ID_CALENDAR=772d2510-c5bb-47e0-b490-267f2821510a
+UMAMI_WEBSITE_ID_TODO=ec1bb158-d871-4bc6-bdbc-147c97b9c1c7
+UMAMI_WEBSITE_ID_SKILLTREE=5de13e08-95ae-4a69-aa2a-834f985be14d
+UMAMI_WEBSITE_ID_ZITARE=6a86139a-d8e2-469c-9754-1c40a70397fa
+UMAMI_WEBSITE_ID_CONTACTS=d2cc0f01-9e46-4a88-a49b-a365f58b78e7
+UMAMI_WEBSITE_ID_PICTURE=273f67fa-5699-40f6-b85e-7a7a0a003539
+UMAMI_WEBSITE_ID_PLANTA=1e83a8a6-7fa8-4d39-9545-5c21dedbe3a2
+UMAMI_WEBSITE_ID_PRESI=a1eb8d1f-a4d5-43e6-b97a-c41351fe1c6f
+UMAMI_WEBSITE_ID_NUTRIPHI=33dfae72-f8e2-4aaa-8008-cbbceeaf072d
+UMAMI_WEBSITE_ID_STORAGE=392ff51d-11f1-4f0c-9d55-6af1402a3ee6
+UMAMI_WEBSITE_ID_PHOTOS=dc201d68-5f78-4716-a0b8-587376eca7a1
+UMAMI_WEBSITE_ID_CLOCK=f893945e-fea7-4493-82ab-f04812a54bea
+UMAMI_WEBSITE_ID_MUKKE=89015bbb-dc59-45b7-ad51-2a68a1391553
+UMAMI_WEBSITE_ID_QUESTIONS=4940b9a8-834a-483a-8696-a3086bd531e6
+UMAMI_WEBSITE_ID_MANADECK=1c1d54c4-7829-43e5-8dde-0a6db7c86ec6
+
# ============================================
# CHAT PROJECT
# ============================================
diff --git a/apps/calendar/apps/web/src/app.html b/apps/calendar/apps/web/src/app.html
index eb6badca1..cff15d4b6 100644
--- a/apps/calendar/apps/web/src/app.html
+++ b/apps/calendar/apps/web/src/app.html
@@ -6,8 +6,6 @@
Calendar
%sveltekit.head%
-
-
%sveltekit.body%
diff --git a/apps/calendar/apps/web/src/hooks.server.ts b/apps/calendar/apps/web/src/hooks.server.ts
index 598e9b52c..872eda7ea 100644
--- a/apps/calendar/apps/web/src/hooks.server.ts
+++ b/apps/calendar/apps/web/src/hooks.server.ts
@@ -6,6 +6,7 @@
*/
import type { Handle } from '@sveltejs/kit';
+import { injectUmamiAnalytics } from '@manacore/shared-utils/analytics-server';
// Get client-side URLs from environment (Docker runtime)
// In dev mode, Vite exposes .env vars via import.meta.env, not process.env
@@ -35,7 +36,7 @@ window.__PUBLIC_STT_URL__ = "${PUBLIC_STT_URL}";
window.__PUBLIC_TODO_BACKEND_URL__ = "${PUBLIC_TODO_BACKEND_URL}";
window.__PUBLIC_CONTACTS_API_URL__ = "${PUBLIC_CONTACTS_API_URL}";
`;
- return html.replace('', `${envScript}`);
+ return injectUmamiAnalytics(html.replace('', `${envScript}`));
},
});
diff --git a/apps/chat/apps/web/src/app.html b/apps/chat/apps/web/src/app.html
index 295eae292..77a5ff52c 100644
--- a/apps/chat/apps/web/src/app.html
+++ b/apps/chat/apps/web/src/app.html
@@ -5,8 +5,6 @@
%sveltekit.head%
-
-
%sveltekit.body%
diff --git a/apps/chat/apps/web/src/hooks.server.ts b/apps/chat/apps/web/src/hooks.server.ts
index 074e8cc90..bbdabf731 100644
--- a/apps/chat/apps/web/src/hooks.server.ts
+++ b/apps/chat/apps/web/src/hooks.server.ts
@@ -5,6 +5,7 @@
*/
import type { Handle } from '@sveltejs/kit';
+import { injectUmamiAnalytics } from '@manacore/shared-utils/analytics-server';
// Get client-side URLs from environment (Docker runtime)
const PUBLIC_MANA_CORE_AUTH_URL_CLIENT =
@@ -22,7 +23,7 @@ export const handle: Handle = async ({ event, resolve }) => {
window.__PUBLIC_MANA_CORE_AUTH_URL__ = ${JSON.stringify(PUBLIC_MANA_CORE_AUTH_URL_CLIENT)};
window.__PUBLIC_BACKEND_URL__ = ${JSON.stringify(PUBLIC_BACKEND_URL_CLIENT)};
`;
- return html.replace('', `${envScript}`);
+ return injectUmamiAnalytics(html.replace('', `${envScript}`));
},
});
};
diff --git a/apps/clock/apps/web/package.json b/apps/clock/apps/web/package.json
index 61d10b1d5..766f99189 100644
--- a/apps/clock/apps/web/package.json
+++ b/apps/clock/apps/web/package.json
@@ -52,6 +52,7 @@
"@manacore/shared-theme": "workspace:*",
"@manacore/shared-theme-ui": "workspace:*",
"@manacore/shared-ui": "workspace:*",
+ "@manacore/shared-utils": "workspace:*",
"d3": "^7.9.0",
"svelte-dnd-action": "^0.9.68",
"svelte-i18n": "^4.0.1",
diff --git a/apps/clock/apps/web/src/app.html b/apps/clock/apps/web/src/app.html
index d72c0848a..77a5ff52c 100644
--- a/apps/clock/apps/web/src/app.html
+++ b/apps/clock/apps/web/src/app.html
@@ -5,8 +5,6 @@
%sveltekit.head%
-
-
%sveltekit.body%
diff --git a/apps/clock/apps/web/src/hooks.server.ts b/apps/clock/apps/web/src/hooks.server.ts
new file mode 100644
index 000000000..dd888a160
--- /dev/null
+++ b/apps/clock/apps/web/src/hooks.server.ts
@@ -0,0 +1,19 @@
+import type { Handle } from '@sveltejs/kit';
+import { injectUmamiAnalytics } from '@manacore/shared-utils/analytics-server';
+
+const PUBLIC_MANA_CORE_AUTH_URL_CLIENT =
+ process.env.PUBLIC_MANA_CORE_AUTH_URL_CLIENT || process.env.PUBLIC_MANA_CORE_AUTH_URL || '';
+const PUBLIC_BACKEND_URL_CLIENT =
+ process.env.PUBLIC_BACKEND_URL_CLIENT || process.env.PUBLIC_BACKEND_URL || '';
+
+export const handle: Handle = async ({ event, resolve }) => {
+ return resolve(event, {
+ transformPageChunk: ({ html }) => {
+ const envScript = ``;
+ return injectUmamiAnalytics(html.replace('', `${envScript}`));
+ },
+ });
+};
diff --git a/apps/contacts/apps/web/src/app.html b/apps/contacts/apps/web/src/app.html
index 9d8916f7d..32f3f1e01 100644
--- a/apps/contacts/apps/web/src/app.html
+++ b/apps/contacts/apps/web/src/app.html
@@ -6,8 +6,6 @@
Kontakte
%sveltekit.head%
-
-
%sveltekit.body%
diff --git a/apps/contacts/apps/web/src/hooks.server.ts b/apps/contacts/apps/web/src/hooks.server.ts
index ee537918b..7b148a6b5 100644
--- a/apps/contacts/apps/web/src/hooks.server.ts
+++ b/apps/contacts/apps/web/src/hooks.server.ts
@@ -5,6 +5,7 @@
*/
import type { Handle } from '@sveltejs/kit';
+import { injectUmamiAnalytics } from '@manacore/shared-utils/analytics-server';
// Get client-side URLs from environment (Docker runtime)
const PUBLIC_MANA_CORE_AUTH_URL_CLIENT =
@@ -25,7 +26,7 @@ window.__PUBLIC_MANA_CORE_AUTH_URL__ = "${PUBLIC_MANA_CORE_AUTH_URL_CLIENT}";
window.__PUBLIC_BACKEND_URL__ = "${PUBLIC_BACKEND_URL_CLIENT}";
window.__PUBLIC_TODO_BACKEND_URL__ = "${PUBLIC_TODO_BACKEND_URL}";
`;
- return html.replace('', `${envScript}`);
+ return injectUmamiAnalytics(html.replace('', `${envScript}`));
},
});
};
diff --git a/apps/manacore/apps/web/src/app.html b/apps/manacore/apps/web/src/app.html
index 9ef077c8c..77a5ff52c 100644
--- a/apps/manacore/apps/web/src/app.html
+++ b/apps/manacore/apps/web/src/app.html
@@ -5,8 +5,6 @@
%sveltekit.head%
-
-
%sveltekit.body%
diff --git a/apps/manacore/apps/web/src/hooks.server.ts b/apps/manacore/apps/web/src/hooks.server.ts
index 21b618758..18e934331 100644
--- a/apps/manacore/apps/web/src/hooks.server.ts
+++ b/apps/manacore/apps/web/src/hooks.server.ts
@@ -1,4 +1,5 @@
import type { Handle } from '@sveltejs/kit';
+import { injectUmamiAnalytics } from '@manacore/shared-utils/analytics-server';
/**
* Server hooks for ManaCore web app
@@ -32,7 +33,7 @@ window.__PUBLIC_CALENDAR_API_URL__ = "${PUBLIC_CALENDAR_API_URL_CLIENT}";
window.__PUBLIC_CLOCK_API_URL__ = "${PUBLIC_CLOCK_API_URL_CLIENT}";
window.__PUBLIC_CONTACTS_API_URL__ = "${PUBLIC_CONTACTS_API_URL_CLIENT}";
`;
- return html.replace('', `${envScript}`);
+ return injectUmamiAnalytics(html.replace('', `${envScript}`));
},
});
};
diff --git a/apps/manadeck/apps/web/src/app.html b/apps/manadeck/apps/web/src/app.html
index 0ac71ff9e..f273cc58f 100644
--- a/apps/manadeck/apps/web/src/app.html
+++ b/apps/manadeck/apps/web/src/app.html
@@ -4,8 +4,6 @@
%sveltekit.head%
-
-
%sveltekit.body%
diff --git a/apps/manadeck/apps/web/src/hooks.server.ts b/apps/manadeck/apps/web/src/hooks.server.ts
new file mode 100644
index 000000000..dd888a160
--- /dev/null
+++ b/apps/manadeck/apps/web/src/hooks.server.ts
@@ -0,0 +1,19 @@
+import type { Handle } from '@sveltejs/kit';
+import { injectUmamiAnalytics } from '@manacore/shared-utils/analytics-server';
+
+const PUBLIC_MANA_CORE_AUTH_URL_CLIENT =
+ process.env.PUBLIC_MANA_CORE_AUTH_URL_CLIENT || process.env.PUBLIC_MANA_CORE_AUTH_URL || '';
+const PUBLIC_BACKEND_URL_CLIENT =
+ process.env.PUBLIC_BACKEND_URL_CLIENT || process.env.PUBLIC_BACKEND_URL || '';
+
+export const handle: Handle = async ({ event, resolve }) => {
+ return resolve(event, {
+ transformPageChunk: ({ html }) => {
+ const envScript = ``;
+ return injectUmamiAnalytics(html.replace('', `${envScript}`));
+ },
+ });
+};
diff --git a/apps/mukke/apps/web/package.json b/apps/mukke/apps/web/package.json
index 743449fd0..084ffa140 100644
--- a/apps/mukke/apps/web/package.json
+++ b/apps/mukke/apps/web/package.json
@@ -50,6 +50,7 @@
"@manacore/shared-theme": "workspace:*",
"@manacore/shared-theme-ui": "workspace:*",
"@manacore/shared-ui": "workspace:*",
+ "@manacore/shared-utils": "workspace:*",
"@mukke/shared": "workspace:*",
"wavesurfer.js": "^7.8.0"
},
diff --git a/apps/mukke/apps/web/src/hooks.server.ts b/apps/mukke/apps/web/src/hooks.server.ts
index 6d7a5089d..e637ac77c 100644
--- a/apps/mukke/apps/web/src/hooks.server.ts
+++ b/apps/mukke/apps/web/src/hooks.server.ts
@@ -5,6 +5,7 @@
*/
import type { Handle } from '@sveltejs/kit';
+import { injectUmamiAnalytics } from '@manacore/shared-utils/analytics-server';
// Get client-side URLs from environment (Docker runtime)
const PUBLIC_MANA_CORE_AUTH_URL_CLIENT =
@@ -21,7 +22,7 @@ export const handle: Handle = async ({ event, resolve }) => {
window.__PUBLIC_MANA_CORE_AUTH_URL__ = "${PUBLIC_MANA_CORE_AUTH_URL_CLIENT}";
window.__PUBLIC_BACKEND_URL__ = "${PUBLIC_BACKEND_URL_CLIENT}";
`;
- return html.replace('', `${envScript}`);
+ return injectUmamiAnalytics(html.replace('', `${envScript}`));
},
});
};
diff --git a/apps/nutriphi/apps/web/src/app.html b/apps/nutriphi/apps/web/src/app.html
index 1b49ff4b5..5e33d0427 100644
--- a/apps/nutriphi/apps/web/src/app.html
+++ b/apps/nutriphi/apps/web/src/app.html
@@ -7,8 +7,6 @@
%sveltekit.head%
-
-
%sveltekit.body%
diff --git a/apps/nutriphi/apps/web/src/hooks.server.ts b/apps/nutriphi/apps/web/src/hooks.server.ts
index 6d7a5089d..e637ac77c 100644
--- a/apps/nutriphi/apps/web/src/hooks.server.ts
+++ b/apps/nutriphi/apps/web/src/hooks.server.ts
@@ -5,6 +5,7 @@
*/
import type { Handle } from '@sveltejs/kit';
+import { injectUmamiAnalytics } from '@manacore/shared-utils/analytics-server';
// Get client-side URLs from environment (Docker runtime)
const PUBLIC_MANA_CORE_AUTH_URL_CLIENT =
@@ -21,7 +22,7 @@ export const handle: Handle = async ({ event, resolve }) => {
window.__PUBLIC_MANA_CORE_AUTH_URL__ = "${PUBLIC_MANA_CORE_AUTH_URL_CLIENT}";
window.__PUBLIC_BACKEND_URL__ = "${PUBLIC_BACKEND_URL_CLIENT}";
`;
- return html.replace('', `${envScript}`);
+ return injectUmamiAnalytics(html.replace('', `${envScript}`));
},
});
};
diff --git a/apps/photos/apps/web/src/app.html b/apps/photos/apps/web/src/app.html
index 412e69e8d..77a5ff52c 100644
--- a/apps/photos/apps/web/src/app.html
+++ b/apps/photos/apps/web/src/app.html
@@ -5,8 +5,6 @@
%sveltekit.head%
-
-
%sveltekit.body%
diff --git a/apps/photos/apps/web/src/hooks.server.ts b/apps/photos/apps/web/src/hooks.server.ts
new file mode 100644
index 000000000..dd888a160
--- /dev/null
+++ b/apps/photos/apps/web/src/hooks.server.ts
@@ -0,0 +1,19 @@
+import type { Handle } from '@sveltejs/kit';
+import { injectUmamiAnalytics } from '@manacore/shared-utils/analytics-server';
+
+const PUBLIC_MANA_CORE_AUTH_URL_CLIENT =
+ process.env.PUBLIC_MANA_CORE_AUTH_URL_CLIENT || process.env.PUBLIC_MANA_CORE_AUTH_URL || '';
+const PUBLIC_BACKEND_URL_CLIENT =
+ process.env.PUBLIC_BACKEND_URL_CLIENT || process.env.PUBLIC_BACKEND_URL || '';
+
+export const handle: Handle = async ({ event, resolve }) => {
+ return resolve(event, {
+ transformPageChunk: ({ html }) => {
+ const envScript = ``;
+ return injectUmamiAnalytics(html.replace('', `${envScript}`));
+ },
+ });
+};
diff --git a/apps/picture/apps/web/package.json b/apps/picture/apps/web/package.json
index c3fee0731..85d524f9c 100644
--- a/apps/picture/apps/web/package.json
+++ b/apps/picture/apps/web/package.json
@@ -32,6 +32,7 @@
"@manacore/shared-theme": "workspace:*",
"@manacore/shared-theme-ui": "workspace:*",
"@manacore/shared-ui": "workspace:*",
+ "@manacore/shared-utils": "workspace:*",
"@picture/design-tokens": "workspace:*",
"@picture/shared": "workspace:*",
"konva": "^10.0.2",
diff --git a/apps/picture/apps/web/src/app.html b/apps/picture/apps/web/src/app.html
index e7c1e0fe2..f273cc58f 100644
--- a/apps/picture/apps/web/src/app.html
+++ b/apps/picture/apps/web/src/app.html
@@ -4,8 +4,6 @@
%sveltekit.head%
-
-
%sveltekit.body%
diff --git a/apps/picture/apps/web/src/hooks.server.ts b/apps/picture/apps/web/src/hooks.server.ts
new file mode 100644
index 000000000..dd888a160
--- /dev/null
+++ b/apps/picture/apps/web/src/hooks.server.ts
@@ -0,0 +1,19 @@
+import type { Handle } from '@sveltejs/kit';
+import { injectUmamiAnalytics } from '@manacore/shared-utils/analytics-server';
+
+const PUBLIC_MANA_CORE_AUTH_URL_CLIENT =
+ process.env.PUBLIC_MANA_CORE_AUTH_URL_CLIENT || process.env.PUBLIC_MANA_CORE_AUTH_URL || '';
+const PUBLIC_BACKEND_URL_CLIENT =
+ process.env.PUBLIC_BACKEND_URL_CLIENT || process.env.PUBLIC_BACKEND_URL || '';
+
+export const handle: Handle = async ({ event, resolve }) => {
+ return resolve(event, {
+ transformPageChunk: ({ html }) => {
+ const envScript = ``;
+ return injectUmamiAnalytics(html.replace('', `${envScript}`));
+ },
+ });
+};
diff --git a/apps/picture/apps/web/src/routes/+layout.svelte b/apps/picture/apps/web/src/routes/+layout.svelte
index eece69687..37068237b 100644
--- a/apps/picture/apps/web/src/routes/+layout.svelte
+++ b/apps/picture/apps/web/src/routes/+layout.svelte
@@ -32,16 +32,6 @@
-
-
- {#if import.meta.env.PUBLIC_UMAMI_WEBSITE_ID && import.meta.env.PUBLIC_UMAMI_URL}
-
- {/if}
{@render children?.()}
diff --git a/apps/planta/apps/web/package.json b/apps/planta/apps/web/package.json
index dc03bafa6..c4115e2d2 100644
--- a/apps/planta/apps/web/package.json
+++ b/apps/planta/apps/web/package.json
@@ -40,6 +40,7 @@
"@manacore/shared-theme": "workspace:*",
"@manacore/shared-theme-ui": "workspace:*",
"@manacore/shared-ui": "workspace:*",
+ "@manacore/shared-utils": "workspace:*",
"@planta/shared": "workspace:*",
"svelte-i18n": "^4.0.1"
},
diff --git a/apps/planta/apps/web/src/app.html b/apps/planta/apps/web/src/app.html
index 0f50a9b7b..41aee8e55 100644
--- a/apps/planta/apps/web/src/app.html
+++ b/apps/planta/apps/web/src/app.html
@@ -6,8 +6,6 @@
Planta - Pflanzendokumentation
%sveltekit.head%
-
-
%sveltekit.body%
diff --git a/apps/planta/apps/web/src/hooks.server.ts b/apps/planta/apps/web/src/hooks.server.ts
new file mode 100644
index 000000000..dd888a160
--- /dev/null
+++ b/apps/planta/apps/web/src/hooks.server.ts
@@ -0,0 +1,19 @@
+import type { Handle } from '@sveltejs/kit';
+import { injectUmamiAnalytics } from '@manacore/shared-utils/analytics-server';
+
+const PUBLIC_MANA_CORE_AUTH_URL_CLIENT =
+ process.env.PUBLIC_MANA_CORE_AUTH_URL_CLIENT || process.env.PUBLIC_MANA_CORE_AUTH_URL || '';
+const PUBLIC_BACKEND_URL_CLIENT =
+ process.env.PUBLIC_BACKEND_URL_CLIENT || process.env.PUBLIC_BACKEND_URL || '';
+
+export const handle: Handle = async ({ event, resolve }) => {
+ return resolve(event, {
+ transformPageChunk: ({ html }) => {
+ const envScript = ``;
+ return injectUmamiAnalytics(html.replace('', `${envScript}`));
+ },
+ });
+};
diff --git a/apps/presi/apps/web/package.json b/apps/presi/apps/web/package.json
index ba826fd1a..cfe8a06c3 100644
--- a/apps/presi/apps/web/package.json
+++ b/apps/presi/apps/web/package.json
@@ -46,6 +46,7 @@
"@manacore/shared-theme": "workspace:*",
"@manacore/shared-theme-ui": "workspace:*",
"@manacore/shared-ui": "workspace:*",
+ "@manacore/shared-utils": "workspace:*",
"svelte-i18n": "^4.0.1"
},
"type": "module"
diff --git a/apps/presi/apps/web/src/app.html b/apps/presi/apps/web/src/app.html
index b9b73d1df..84ffad166 100644
--- a/apps/presi/apps/web/src/app.html
+++ b/apps/presi/apps/web/src/app.html
@@ -5,8 +5,6 @@
%sveltekit.head%
-
-
%sveltekit.body%
diff --git a/apps/presi/apps/web/src/hooks.server.ts b/apps/presi/apps/web/src/hooks.server.ts
new file mode 100644
index 000000000..dd888a160
--- /dev/null
+++ b/apps/presi/apps/web/src/hooks.server.ts
@@ -0,0 +1,19 @@
+import type { Handle } from '@sveltejs/kit';
+import { injectUmamiAnalytics } from '@manacore/shared-utils/analytics-server';
+
+const PUBLIC_MANA_CORE_AUTH_URL_CLIENT =
+ process.env.PUBLIC_MANA_CORE_AUTH_URL_CLIENT || process.env.PUBLIC_MANA_CORE_AUTH_URL || '';
+const PUBLIC_BACKEND_URL_CLIENT =
+ process.env.PUBLIC_BACKEND_URL_CLIENT || process.env.PUBLIC_BACKEND_URL || '';
+
+export const handle: Handle = async ({ event, resolve }) => {
+ return resolve(event, {
+ transformPageChunk: ({ html }) => {
+ const envScript = ``;
+ return injectUmamiAnalytics(html.replace('', `${envScript}`));
+ },
+ });
+};
diff --git a/apps/questions/apps/web/src/hooks.server.ts b/apps/questions/apps/web/src/hooks.server.ts
new file mode 100644
index 000000000..dd888a160
--- /dev/null
+++ b/apps/questions/apps/web/src/hooks.server.ts
@@ -0,0 +1,19 @@
+import type { Handle } from '@sveltejs/kit';
+import { injectUmamiAnalytics } from '@manacore/shared-utils/analytics-server';
+
+const PUBLIC_MANA_CORE_AUTH_URL_CLIENT =
+ process.env.PUBLIC_MANA_CORE_AUTH_URL_CLIENT || process.env.PUBLIC_MANA_CORE_AUTH_URL || '';
+const PUBLIC_BACKEND_URL_CLIENT =
+ process.env.PUBLIC_BACKEND_URL_CLIENT || process.env.PUBLIC_BACKEND_URL || '';
+
+export const handle: Handle = async ({ event, resolve }) => {
+ return resolve(event, {
+ transformPageChunk: ({ html }) => {
+ const envScript = ``;
+ return injectUmamiAnalytics(html.replace('', `${envScript}`));
+ },
+ });
+};
diff --git a/apps/skilltree/apps/web/src/app.html b/apps/skilltree/apps/web/src/app.html
index 2ca7377f4..0b9a66d8c 100644
--- a/apps/skilltree/apps/web/src/app.html
+++ b/apps/skilltree/apps/web/src/app.html
@@ -16,8 +16,6 @@
%sveltekit.head%
-
-
%sveltekit.body%
diff --git a/apps/skilltree/apps/web/src/hooks.server.ts b/apps/skilltree/apps/web/src/hooks.server.ts
index a450239b2..0868fabf7 100644
--- a/apps/skilltree/apps/web/src/hooks.server.ts
+++ b/apps/skilltree/apps/web/src/hooks.server.ts
@@ -5,6 +5,7 @@
*/
import type { Handle } from '@sveltejs/kit';
+import { injectUmamiAnalytics } from '@manacore/shared-utils/analytics-server';
const PUBLIC_MANA_CORE_AUTH_URL_CLIENT =
process.env.PUBLIC_MANA_CORE_AUTH_URL_CLIENT || process.env.PUBLIC_MANA_CORE_AUTH_URL || '';
@@ -18,7 +19,7 @@ export const handle: Handle = async ({ event, resolve }) => {
window.__PUBLIC_MANA_CORE_AUTH_URL__ = "${PUBLIC_MANA_CORE_AUTH_URL_CLIENT}";
window.__PUBLIC_BACKEND_URL__ = "${PUBLIC_BACKEND_URL_CLIENT}";
`;
- return html.replace('', `${envScript}`);
+ return injectUmamiAnalytics(html.replace('', `${envScript}`));
},
});
};
diff --git a/apps/storage/apps/web/package.json b/apps/storage/apps/web/package.json
index 31afb18aa..7410b5981 100644
--- a/apps/storage/apps/web/package.json
+++ b/apps/storage/apps/web/package.json
@@ -53,6 +53,7 @@
"@manacore/shared-theme": "workspace:*",
"@manacore/shared-theme-ui": "workspace:*",
"@manacore/shared-ui": "workspace:*",
+ "@manacore/shared-utils": "workspace:*",
"svelte-i18n": "^4.0.1"
},
"type": "module"
diff --git a/apps/storage/apps/web/src/app.html b/apps/storage/apps/web/src/app.html
index 7eeacac36..81cc103c3 100644
--- a/apps/storage/apps/web/src/app.html
+++ b/apps/storage/apps/web/src/app.html
@@ -11,11 +11,7 @@
Storage - Cloud Drive
-
-
%sveltekit.head%
-
-
%sveltekit.body%
diff --git a/apps/todo/apps/web/src/app.html b/apps/todo/apps/web/src/app.html
index ab2442430..e09d2346a 100644
--- a/apps/todo/apps/web/src/app.html
+++ b/apps/todo/apps/web/src/app.html
@@ -17,8 +17,6 @@
Todo
%sveltekit.head%
-
-
%sveltekit.body%
diff --git a/apps/todo/apps/web/src/hooks.server.ts b/apps/todo/apps/web/src/hooks.server.ts
index 6d7a5089d..e637ac77c 100644
--- a/apps/todo/apps/web/src/hooks.server.ts
+++ b/apps/todo/apps/web/src/hooks.server.ts
@@ -5,6 +5,7 @@
*/
import type { Handle } from '@sveltejs/kit';
+import { injectUmamiAnalytics } from '@manacore/shared-utils/analytics-server';
// Get client-side URLs from environment (Docker runtime)
const PUBLIC_MANA_CORE_AUTH_URL_CLIENT =
@@ -21,7 +22,7 @@ export const handle: Handle = async ({ event, resolve }) => {
window.__PUBLIC_MANA_CORE_AUTH_URL__ = "${PUBLIC_MANA_CORE_AUTH_URL_CLIENT}";
window.__PUBLIC_BACKEND_URL__ = "${PUBLIC_BACKEND_URL_CLIENT}";
`;
- return html.replace('', `${envScript}`);
+ return injectUmamiAnalytics(html.replace('', `${envScript}`));
},
});
};
diff --git a/apps/zitare/apps/web/src/app.html b/apps/zitare/apps/web/src/app.html
index e4f70b844..dca4f7d63 100644
--- a/apps/zitare/apps/web/src/app.html
+++ b/apps/zitare/apps/web/src/app.html
@@ -8,8 +8,6 @@
Zitare
%sveltekit.head%
-
-
%sveltekit.body%
diff --git a/apps/zitare/apps/web/src/hooks.server.ts b/apps/zitare/apps/web/src/hooks.server.ts
index 65be9d02d..2b1537518 100644
--- a/apps/zitare/apps/web/src/hooks.server.ts
+++ b/apps/zitare/apps/web/src/hooks.server.ts
@@ -5,6 +5,7 @@
*/
import type { Handle } from '@sveltejs/kit';
+import { injectUmamiAnalytics } from '@manacore/shared-utils/analytics-server';
// Get client-side URLs from environment (Docker runtime)
const PUBLIC_MANA_CORE_AUTH_URL_CLIENT =
@@ -21,7 +22,7 @@ export const handle: Handle = async ({ event, resolve }) => {
window.__PUBLIC_MANA_CORE_AUTH_URL__ = "${PUBLIC_MANA_CORE_AUTH_URL_CLIENT}";
window.__PUBLIC_BACKEND_URL__ = "${PUBLIC_BACKEND_URL_CLIENT}";
`;
- return html.replace('', `${envScript}`);
+ return injectUmamiAnalytics(html.replace('', `${envScript}`));
},
});
};
diff --git a/docs/ANALYTICS.md b/docs/ANALYTICS.md
index 68c391060..317ff570a 100644
--- a/docs/ANALYTICS.md
+++ b/docs/ANALYTICS.md
@@ -7,6 +7,35 @@ ManaCore verwendet Umami für Web Analytics. Alle Events werden zu `stats.mana.h
- **URL**: https://stats.mana.how
- **Public Stats**: Alle Websites haben Public Sharing aktiviert
+## Architektur
+
+Web-App Analytics werden über `hooks.server.ts` injiziert (nicht mehr hardcoded in `app.html`).
+
+```
+.env.development → UMAMI_WEBSITE_ID_CHAT=xxx
+ ↓ (scripts/generate-env.mjs)
+apps/chat/apps/web/.env → PUBLIC_UMAMI_WEBSITE_ID=xxx
+ ↓ (process.env in hooks.server.ts)
+injectUmamiAnalytics(html) → `;
+}
+
+/**
+ * Inject the Umami analytics script into HTML.
+ * Designed to be used in SvelteKit's transformPageChunk.
+ *
+ * @param html - The HTML string to inject the script into
+ * @param websiteId - Optional website ID override (defaults to PUBLIC_UMAMI_WEBSITE_ID env var)
+ * @returns The HTML with the Umami script injected before
+ */
+export function injectUmamiAnalytics(html: string, websiteId?: string): string {
+ const scriptTag = getUmamiScriptTag(websiteId);
+ if (!scriptTag) return html;
+ return html.replace('', `${scriptTag}\n`);
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 277715191..df413c50d 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1036,6 +1036,9 @@ importers:
'@manacore/shared-ui':
specifier: workspace:*
version: link:../../../../packages/shared-ui
+ '@manacore/shared-utils':
+ specifier: workspace:*
+ version: link:../../../../packages/shared-utils
d3:
specifier: ^7.9.0
version: 7.9.0
@@ -2943,6 +2946,9 @@ importers:
'@manacore/shared-ui':
specifier: workspace:*
version: link:../../../../packages/shared-ui
+ '@manacore/shared-utils':
+ specifier: workspace:*
+ version: link:../../../../packages/shared-utils
'@mukke/shared':
specifier: workspace:*
version: link:../../packages/shared
@@ -3952,6 +3958,9 @@ importers:
'@manacore/shared-ui':
specifier: workspace:*
version: link:../../../../packages/shared-ui
+ '@manacore/shared-utils':
+ specifier: workspace:*
+ version: link:../../../../packages/shared-utils
'@picture/design-tokens':
specifier: workspace:*
version: link:../../packages/design-tokens
@@ -4247,6 +4256,9 @@ importers:
'@manacore/shared-ui':
specifier: workspace:*
version: link:../../../../packages/shared-ui
+ '@manacore/shared-utils':
+ specifier: workspace:*
+ version: link:../../../../packages/shared-utils
'@planta/shared':
specifier: workspace:*
version: link:../../packages/shared
@@ -4587,6 +4599,9 @@ importers:
'@manacore/shared-ui':
specifier: workspace:*
version: link:../../../../packages/shared-ui
+ '@manacore/shared-utils':
+ specifier: workspace:*
+ version: link:../../../../packages/shared-utils
'@presi/shared':
specifier: workspace:*
version: link:../../packages/shared
@@ -5197,6 +5212,9 @@ importers:
'@manacore/shared-ui':
specifier: workspace:*
version: link:../../../../packages/shared-ui
+ '@manacore/shared-utils':
+ specifier: workspace:*
+ version: link:../../../../packages/shared-utils
svelte-i18n:
specifier: ^4.0.1
version: 4.0.1(svelte@5.44.0)
diff --git a/scripts/generate-env.mjs b/scripts/generate-env.mjs
index f43ba916d..052b4fc37 100644
--- a/scripts/generate-env.mjs
+++ b/scripts/generate-env.mjs
@@ -118,6 +118,7 @@ const APP_CONFIGS = [
PUBLIC_SUPABASE_URL: (env) => env.CHAT_SUPABASE_URL,
PUBLIC_SUPABASE_ANON_KEY: (env) => env.CHAT_SUPABASE_ANON_KEY,
PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.CHAT_BACKEND_PORT || '3002'}`,
+ PUBLIC_UMAMI_WEBSITE_ID: (env) => env.UMAMI_WEBSITE_ID_CHAT || '',
},
},
@@ -137,6 +138,7 @@ const APP_CONFIGS = [
PUBLIC_SUPABASE_URL: (env) => env.MANACORE_SUPABASE_URL,
PUBLIC_SUPABASE_ANON_KEY: (env) => env.MANACORE_SUPABASE_ANON_KEY,
MIDDLEWARE_URL: (env) => env.MANA_CORE_AUTH_URL,
+ PUBLIC_UMAMI_WEBSITE_ID: (env) => env.UMAMI_WEBSITE_ID_MANACORE || '',
},
},
@@ -181,6 +183,7 @@ const APP_CONFIGS = [
PUBLIC_SUPABASE_ANON_KEY: (env) => env.MANADECK_SUPABASE_ANON_KEY,
PUBLIC_API_URL: (env) => `http://localhost:${env.MANADECK_BACKEND_PORT || '3004'}`,
PUBLIC_MANA_CORE_AUTH_URL: (env) => env.MANA_CORE_AUTH_URL,
+ PUBLIC_UMAMI_WEBSITE_ID: (env) => env.UMAMI_WEBSITE_ID_MANADECK || '',
},
},
@@ -231,6 +234,7 @@ const APP_CONFIGS = [
PUBLIC_MANA_CORE_AUTH_URL: (env) => env.MANA_CORE_AUTH_URL,
PUBLIC_GOOGLE_CLIENT_ID: (env) => env.PICTURE_GOOGLE_CLIENT_ID || '',
PUBLIC_APPLE_CLIENT_ID: (env) => env.PICTURE_APPLE_CLIENT_ID || '',
+ PUBLIC_UMAMI_WEBSITE_ID: (env) => env.UMAMI_WEBSITE_ID_PICTURE || '',
},
},
@@ -259,6 +263,7 @@ const APP_CONFIGS = [
PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.NUTRIPHI_BACKEND_PORT || '3002'}`,
PUBLIC_MANA_CORE_AUTH_URL: (env) => env.MANA_CORE_AUTH_URL,
PUBLIC_MIDDLEWARE_APP_ID: (env) => env.NUTRIPHI_APP_ID || 'nutriphi',
+ PUBLIC_UMAMI_WEBSITE_ID: (env) => env.UMAMI_WEBSITE_ID_NUTRIPHI || '',
},
},
@@ -291,6 +296,7 @@ const APP_CONFIGS = [
vars: {
PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.ZITARE_BACKEND_PORT || '3007'}`,
PUBLIC_MANA_CORE_AUTH_URL: (env) => env.MANA_CORE_AUTH_URL,
+ PUBLIC_UMAMI_WEBSITE_ID: (env) => env.UMAMI_WEBSITE_ID_ZITARE || '',
},
},
@@ -324,6 +330,7 @@ const APP_CONFIGS = [
vars: {
PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.PRESI_BACKEND_PORT || '3008'}`,
PUBLIC_MANA_CORE_AUTH_URL: (env) => env.MANA_CORE_AUTH_URL,
+ PUBLIC_UMAMI_WEBSITE_ID: (env) => env.UMAMI_WEBSITE_ID_PRESI || '',
},
},
@@ -348,6 +355,7 @@ const APP_CONFIGS = [
vars: {
PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.SKILLTREE_BACKEND_PORT || '3024'}`,
PUBLIC_MANA_CORE_AUTH_URL: (env) => env.MANA_CORE_AUTH_URL,
+ PUBLIC_UMAMI_WEBSITE_ID: (env) => env.UMAMI_WEBSITE_ID_SKILLTREE || '',
},
},
@@ -443,6 +451,7 @@ const APP_CONFIGS = [
PUBLIC_CONTACTS_WEB_URL: () => 'http://localhost:5184',
// Speech-to-Text Service
PUBLIC_STT_URL: (env) => env.STT_URL || 'http://localhost:3020',
+ PUBLIC_UMAMI_WEBSITE_ID: (env) => env.UMAMI_WEBSITE_ID_CALENDAR || '',
},
},
@@ -484,6 +493,7 @@ const APP_CONFIGS = [
vars: {
PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.CONTACTS_BACKEND_PORT || '3015'}`,
PUBLIC_MANA_CORE_AUTH_URL: (env) => env.MANA_CORE_AUTH_URL,
+ PUBLIC_UMAMI_WEBSITE_ID: (env) => env.UMAMI_WEBSITE_ID_CONTACTS || '',
},
},
@@ -514,6 +524,7 @@ const APP_CONFIGS = [
vars: {
PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.STORAGE_BACKEND_PORT || '3016'}`,
PUBLIC_MANA_CORE_AUTH_URL: (env) => env.MANA_CORE_AUTH_URL,
+ PUBLIC_UMAMI_WEBSITE_ID: (env) => env.UMAMI_WEBSITE_ID_STORAGE || '',
},
},
@@ -537,6 +548,7 @@ const APP_CONFIGS = [
vars: {
PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.CLOCK_BACKEND_PORT || '3017'}`,
PUBLIC_MANA_CORE_AUTH_URL: (env) => env.MANA_CORE_AUTH_URL,
+ PUBLIC_UMAMI_WEBSITE_ID: (env) => env.UMAMI_WEBSITE_ID_CLOCK || '',
},
},
@@ -560,6 +572,7 @@ const APP_CONFIGS = [
vars: {
PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.TODO_BACKEND_PORT || '3018'}`,
PUBLIC_MANA_CORE_AUTH_URL: (env) => env.MANA_CORE_AUTH_URL,
+ PUBLIC_UMAMI_WEBSITE_ID: (env) => env.UMAMI_WEBSITE_ID_TODO || '',
},
},
@@ -688,6 +701,36 @@ const APP_CONFIGS = [
},
},
+ // Photos Web (SvelteKit)
+ {
+ path: 'apps/photos/apps/web/.env',
+ vars: {
+ PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.PHOTOS_BACKEND_PORT || '3039'}`,
+ PUBLIC_MANA_CORE_AUTH_URL: (env) => env.MANA_CORE_AUTH_URL,
+ PUBLIC_UMAMI_WEBSITE_ID: (env) => env.UMAMI_WEBSITE_ID_PHOTOS || '',
+ },
+ },
+
+ // Planta Web (SvelteKit)
+ {
+ path: 'apps/planta/apps/web/.env',
+ vars: {
+ PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.PLANTA_BACKEND_PORT || '3022'}`,
+ PUBLIC_MANA_CORE_AUTH_URL: (env) => env.MANA_CORE_AUTH_URL,
+ PUBLIC_UMAMI_WEBSITE_ID: (env) => env.UMAMI_WEBSITE_ID_PLANTA || '',
+ },
+ },
+
+ // Questions Web (SvelteKit)
+ {
+ path: 'apps/questions/apps/web/.env',
+ vars: {
+ PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.QUESTIONS_BACKEND_PORT || '3011'}`,
+ PUBLIC_MANA_CORE_AUTH_URL: (env) => env.MANA_CORE_AUTH_URL,
+ PUBLIC_UMAMI_WEBSITE_ID: (env) => env.UMAMI_WEBSITE_ID_QUESTIONS || '',
+ },
+ },
+
// Mukke Backend (NestJS)
{
path: 'apps/mukke/apps/backend/.env',
@@ -713,6 +756,7 @@ const APP_CONFIGS = [
vars: {
PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.MUKKE_BACKEND_PORT || '3010'}`,
PUBLIC_MANA_CORE_AUTH_URL: (env) => env.MANA_CORE_AUTH_URL,
+ PUBLIC_UMAMI_WEBSITE_ID: (env) => env.UMAMI_WEBSITE_ID_MUKKE || '',
},
},