diff --git a/apps/basic-integration/sveltekit/CMSaasStarter/.env.example b/apps/basic-integration/sveltekit/CMSaasStarter/.env.example
index 04e92240a..dcf3d5d4e 100644
--- a/apps/basic-integration/sveltekit/CMSaasStarter/.env.example
+++ b/apps/basic-integration/sveltekit/CMSaasStarter/.env.example
@@ -6,6 +6,10 @@ PRIVATE_SUPABASE_SERVICE_ROLE='REPLACE_ME'
# Stripe settings
PRIVATE_STRIPE_API_KEY='REPLACE_ME'
+# PostHog settings
+PUBLIC_POSTHOG_PROJECT_TOKEN='your_posthog_project_token_here'
+PUBLIC_POSTHOG_HOST='https://us.i.posthog.com'
+
# Optional - settings for email
# Email address admin messages will be sent to
diff --git a/apps/basic-integration/sveltekit/CMSaasStarter/package-lock.json b/apps/basic-integration/sveltekit/CMSaasStarter/package-lock.json
index 04d318971..922fdbe97 100644
--- a/apps/basic-integration/sveltekit/CMSaasStarter/package-lock.json
+++ b/apps/basic-integration/sveltekit/CMSaasStarter/package-lock.json
@@ -13,6 +13,7 @@
"@supabase/ssr": "^0.5.2",
"@supabase/supabase-js": "^2.45.2",
"handlebars": "^4.7.8",
+ "posthog-js": "^1.438.13",
"resend": "^3.5.0",
"stripe": "^13.3.0"
},
@@ -800,6 +801,31 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@posthog/browser-common": {
+ "version": "0.9.5",
+ "resolved": "https://registry.npmjs.org/@posthog/browser-common/-/browser-common-0.9.5.tgz",
+ "integrity": "sha512-oXnBgZvM8UQ84IcBLfGP0WSGd9rA0PCGR37H8Pw0NszJRwxwbJnFXIUih0pvI/ze2eGmzkIEC9i3SwC+bMAgjQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@posthog/core": "^1.59.1",
+ "@posthog/types": "^1.416.0"
+ }
+ },
+ "node_modules/@posthog/core": {
+ "version": "1.59.3",
+ "resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.59.3.tgz",
+ "integrity": "sha512-XbfpD82YSms/asHU44xQq5vqadi6rHTRg6fyoTqjdGTiC1NiPRCeO8xhtANT682BkvlKJo+JwRDBu3Q8oEqQpw==",
+ "license": "MIT",
+ "dependencies": {
+ "@posthog/types": "^1.416.0"
+ }
+ },
+ "node_modules/@posthog/types": {
+ "version": "1.416.0",
+ "resolved": "https://registry.npmjs.org/@posthog/types/-/types-1.416.0.tgz",
+ "integrity": "sha512-0/9+02s/0uDyrH4G/qUg1yyl6gXUg8Uuxw/PlDad3KLzo9FFS9zS/kAQaEshx/saVGupj1aAy/4EUBxWisBogw==",
+ "license": "MIT"
+ },
"node_modules/@react-email/render": {
"version": "0.0.16",
"resolved": "https://registry.npmjs.org/@react-email/render/-/render-0.0.16.tgz",
@@ -1214,7 +1240,6 @@
"resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.90.1.tgz",
"integrity": "sha512-U8KaKGLUgTIFHtwEW1dgw1gK7XrdpvvYo7nzzqPx721GqPe8WZbAiLh/hmyKLGBYQ/mmQNr20vU9tWSDZpii3w==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@supabase/auth-js": "2.90.1",
"@supabase/functions-js": "2.90.1",
@@ -1255,7 +1280,6 @@
"integrity": "sha512-dCYqelr2RVnWUuxc+Dk/dB/SjV/8JBndp1UovCyCZdIQezd8TRwFLNZctYkzgHxRJtaNvseCSRsuuHPeUgIN/A==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@standard-schema/spec": "^1.0.0",
"@sveltejs/acorn-typescript": "^1.0.5",
@@ -1299,7 +1323,6 @@
"integrity": "sha512-MCFS6CrQDu1yGwspm4qtli0e63vaPCehf6V7pIMP15AsWgMKrqDGCPFF/0kn4SP0ii4aySu4Pa62+fIRGFMjgw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@sveltejs/vite-plugin-svelte-inspector": "^4.0.1",
"debug": "^4.4.0",
@@ -1682,6 +1705,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/trusted-types": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+ "license": "MIT",
+ "optional": true
+ },
"node_modules/@types/ws": {
"version": "8.18.1",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
@@ -1733,7 +1763,6 @@
"integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
"dev": true,
"license": "BSD-2-Clause",
- "peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "6.21.0",
"@typescript-eslint/types": "6.21.0",
@@ -2024,7 +2053,6 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
"license": "MIT",
- "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -2515,6 +2543,20 @@
"node": ">= 0.6"
}
},
+ "node_modules/core-js": {
+ "version": "3.51.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.51.0.tgz",
+ "integrity": "sha512-7bDKx/5jm5MxzsXxc93g6Z2+4ZsuT/MddrfRmTDJNAkWsYWHU8EVNEsBiIEWnMAMCHMmRfUEjkuo3jeNBOIHRw==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -2798,6 +2840,15 @@
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
+ "node_modules/dompurify": {
+ "version": "3.4.17",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.17.tgz",
+ "integrity": "sha512-B/pSlYVHQ58kqISD/yDjuJ1yfzI34m1gF4lAod2bwSRhiN4K5Cl3H8Af7hqB2PmTL911tdEudnnXn5FnhRoz0w==",
+ "license": "(MPL-2.0 OR Apache-2.0)",
+ "optionalDependencies": {
+ "@types/trusted-types": "^2.0.7"
+ }
+ },
"node_modules/domutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
@@ -3011,7 +3062,6 @@
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
@@ -3378,6 +3428,12 @@
"reusify": "^1.0.4"
}
},
+ "node_modules/fflate": {
+ "version": "0.4.9",
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.9.tgz",
+ "integrity": "sha512-zdxgIEddhfsyCaWpJ2SdXEP8ZMrKJ6+5jl4OupODcywU0IhRk6gdXuVGcPICyfx2H97hVK7xmJtRLPjkxAX8Vw==",
+ "license": "MIT"
+ },
"node_modules/file-entry-cache": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@@ -4042,7 +4098,8 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/js-yaml": {
"version": "4.1.1",
@@ -4500,6 +4557,7 @@
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
},
@@ -4938,7 +4996,6 @@
}
],
"license": "MIT",
- "peer": true,
"dependencies": {
"nanoid": "^3.3.8",
"picocolors": "^1.1.1",
@@ -5046,6 +5103,54 @@
"node": ">=4"
}
},
+ "node_modules/posthog-js": {
+ "version": "1.438.13",
+ "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.438.13.tgz",
+ "integrity": "sha512-fcRhMZ/TKvpDjmDGTlf4KCBqqTnpLWLplZ76NfeLNEE1P6N6qCGGZzqZ6gEzJoOfYLNLgjd0sRM5fC8F/Ky9fA==",
+ "license": "(Apache-2.0 AND MIT)",
+ "dependencies": {
+ "@posthog/browser-common": "^0.9.5",
+ "@posthog/core": "^1.59.1",
+ "@posthog/types": "^1.416.0",
+ "core-js": "^3.49.0",
+ "dompurify": "^3.4.13",
+ "fflate": "^0.4.8",
+ "preact": "^10.29.3",
+ "query-selector-shadow-dom": "^1.0.1",
+ "web-vitals": "^6.2.1",
+ "web-vitals-soft-navs": "npm:web-vitals@6.2.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0",
+ "react": ">=16.8.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/preact": {
+ "version": "10.29.8",
+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.29.8.tgz",
+ "integrity": "sha512-ej2aVZ+vZ8WO7tvlQWRM9N63A0KzF9q4mWJfDUHgYaIofWY9hu74QdnQrjoPMmZi2/nZ5gN0bJCQF49xQqx09Q==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ },
+ "peerDependencies": {
+ "preact-render-to-string": ">=5"
+ },
+ "peerDependenciesMeta": {
+ "preact-render-to-string": {
+ "optional": true
+ }
+ }
+ },
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -5062,7 +5167,6 @@
"integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
@@ -5128,6 +5232,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/query-selector-shadow-dom": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.1.tgz",
+ "integrity": "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==",
+ "license": "MIT"
+ },
"node_modules/querystringify": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
@@ -5433,6 +5543,7 @@
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
}
@@ -5810,7 +5921,6 @@
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.14.0.tgz",
"integrity": "sha512-xHrS9dd2Ci9GJd2sReNFqJztoe515wB4OzsPw4A8L2M6lddLFkREkWDJnM5DAND30Zyvjwc1icQVzH0F+Sdx5A==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@ampproject/remapping": "^2.3.0",
"@jridgewell/sourcemap-codec": "^1.5.0",
@@ -5945,8 +6055,7 @@
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.9.tgz",
"integrity": "sha512-12laZu+fv1ONDRoNR9ipTOpUD7RN9essRVkX36sjxuRUInpN7hIiHN4lBd/SIFjbISvnXzp8h/hXzmU8SQQYhw==",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/tapable": {
"version": "2.2.1",
@@ -6017,7 +6126,6 @@
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=12"
},
@@ -6145,7 +6253,6 @@
"integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==",
"dev": true,
"license": "Apache-2.0",
- "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -6227,7 +6334,6 @@
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.4.4",
@@ -6341,7 +6447,6 @@
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=12"
},
@@ -6451,6 +6556,19 @@
"node": ">=18"
}
},
+ "node_modules/web-vitals": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-6.2.3.tgz",
+ "integrity": "sha512-Dmy+vdO1UPMqXiAtZSNayhl4f794Bxfd94W4HIj2HlYtczEQfEOon969memlcpcHrTuOKLa5baFjX7WbgmOq+A==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/web-vitals-soft-navs": {
+ "name": "web-vitals",
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-6.2.1.tgz",
+ "integrity": "sha512-rLcLXA2sx6+9dE88NHFubwTtGxpK4yYBLj6qHPdFoCaLr0cXGb4efOqtKLlm4loGA4OEKHIQKMKzZkKyOh5ctw==",
+ "license": "Apache-2.0"
+ },
"node_modules/webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
diff --git a/apps/basic-integration/sveltekit/CMSaasStarter/package.json b/apps/basic-integration/sveltekit/CMSaasStarter/package.json
index be50d6ac6..7777c86bc 100644
--- a/apps/basic-integration/sveltekit/CMSaasStarter/package.json
+++ b/apps/basic-integration/sveltekit/CMSaasStarter/package.json
@@ -51,6 +51,7 @@
"@supabase/ssr": "^0.5.2",
"@supabase/supabase-js": "^2.45.2",
"handlebars": "^4.7.8",
+ "posthog-js": "^1.438.13",
"resend": "^3.5.0",
"stripe": "^13.3.0"
},
diff --git a/apps/basic-integration/sveltekit/CMSaasStarter/src/hooks.client.ts b/apps/basic-integration/sveltekit/CMSaasStarter/src/hooks.client.ts
new file mode 100644
index 000000000..f64ede3f2
--- /dev/null
+++ b/apps/basic-integration/sveltekit/CMSaasStarter/src/hooks.client.ts
@@ -0,0 +1,41 @@
+import { dev } from "$app/environment"
+import { env } from "$env/dynamic/public"
+import type { HandleClientError } from "@sveltejs/kit"
+import posthog from "posthog-js"
+
+export async function init() {
+ if (!env.PUBLIC_POSTHOG_PROJECT_TOKEN) {
+ if (dev) {
+ throw new Error(
+ "PUBLIC_POSTHOG_PROJECT_TOKEN variable required by PostHog is missing or un-configured, this causes events to be silently missed. This error stops appearing once PUBLIC_POSTHOG_PROJECT_TOKEN is configured",
+ )
+ }
+ return
+ }
+
+ if (!env.PUBLIC_POSTHOG_HOST) {
+ if (dev) {
+ throw new Error(
+ "PUBLIC_POSTHOG_HOST variable required by PostHog is missing or un-configured, this causes events to be silently missed. This error stops appearing once PUBLIC_POSTHOG_HOST is configured",
+ )
+ }
+ return
+ }
+
+ posthog.init(env.PUBLIC_POSTHOG_PROJECT_TOKEN, {
+ api_host: env.PUBLIC_POSTHOG_HOST,
+ capture_exceptions: true,
+ logs: {
+ serviceName: "cm-saas-starter-web",
+ environment: dev ? "development" : "production",
+ },
+ })
+}
+
+export const handleError: HandleClientError = ({ error, message }) => {
+ if (env.PUBLIC_POSTHOG_PROJECT_TOKEN && env.PUBLIC_POSTHOG_HOST) {
+ posthog.captureException(error)
+ }
+
+ return { message }
+}
diff --git a/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/change_email/+page.svelte b/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/change_email/+page.svelte
index c26d536ce..81aca08d3 100644
--- a/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/change_email/+page.svelte
+++ b/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/change_email/+page.svelte
@@ -22,6 +22,7 @@
editable={true}
successTitle="Email change initiated"
successBody="You should receive emails at both the old and new address to confirm the change. Please click the link in both emails to finalized the change. Until finalized, you must sign in with your current email."
+ analyticsEvent="email_change_initiated"
formTarget="/account/api?/updateEmail"
fields={[
{
diff --git a/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/change_email_subscription/+page.svelte b/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/change_email_subscription/+page.svelte
index d5905920a..3106ed2af 100644
--- a/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/change_email_subscription/+page.svelte
+++ b/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/change_email_subscription/+page.svelte
@@ -18,6 +18,7 @@
? "You are currently unsubscribed from emails"
: "You are currently subscribed to emails"}
saveButtonTitle={unsubscribed ? "Re-subscribe" : "Unsubscribe"}
+ analyticsEvent="email_subscription_updated"
successBody={unsubscribed
? "You have been re-subscribed to emails"
: "You have been unsubscribed from emails"}
diff --git a/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/edit_profile/+page.svelte b/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/edit_profile/+page.svelte
index e6099d3c1..07ed79824 100644
--- a/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/edit_profile/+page.svelte
+++ b/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/edit_profile/+page.svelte
@@ -21,6 +21,7 @@
editable={true}
title="Edit Profile"
successTitle="Saved Profile"
+ analyticsEvent="profile_updated"
formTarget="/account/api?/updateProfile"
fields={[
{
diff --git a/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/reset_password/+page.svelte b/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/reset_password/+page.svelte
index e8a7dcf7d..7cf7a2131 100644
--- a/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/reset_password/+page.svelte
+++ b/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/reset_password/+page.svelte
@@ -19,6 +19,7 @@
saveButtonTitle="Reset Password"
successTitle="Password Changed"
successBody="On next sign in, use your new password."
+ analyticsEvent="password_updated"
formTarget="/account/api?/updatePassword"
fields={[
{
diff --git a/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/settings_module.svelte b/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/settings_module.svelte
index 6b115cada..b7ca6122a 100644
--- a/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/settings_module.svelte
+++ b/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/(menu)/settings/settings_module.svelte
@@ -2,6 +2,7 @@
import { enhance, applyAction } from "$app/forms"
import { page } from "$app/stores"
import type { SubmitFunction } from "@sveltejs/kit"
+ import posthog from "posthog-js"
const fieldError = (liveForm: FormAccountUpdateResult, name: string) => {
let errors = liveForm?.errorFields ?? []
@@ -34,6 +35,7 @@
editButtonTitle?: string | null
editLink?: string | null
saveButtonTitle?: string
+ analyticsEvent?: string
}
let {
@@ -48,6 +50,7 @@
editButtonTitle = null,
editLink = null,
saveButtonTitle = "Save",
+ analyticsEvent,
}: Props = $props()
const handleSubmit: SubmitFunction = () => {
@@ -57,6 +60,9 @@
await applyAction(result)
loading = false
if (result.type === "success") {
+ if (analyticsEvent) {
+ posthog.capture(analyticsEvent)
+ }
showSuccess = true
}
}
diff --git a/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/+layout.svelte b/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/+layout.svelte
index 1a9259171..e7ba182be 100644
--- a/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/+layout.svelte
+++ b/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(admin)/account/+layout.svelte
@@ -1,16 +1,42 @@
diff --git a/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(marketing)/contact_us/+page.svelte b/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(marketing)/contact_us/+page.svelte
index 489d5019e..b37210da7 100644
--- a/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(marketing)/contact_us/+page.svelte
+++ b/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(marketing)/contact_us/+page.svelte
@@ -2,6 +2,7 @@
import { enhance, applyAction } from "$app/forms"
import type { SubmitFunction } from "@sveltejs/kit"
import type { FullAutoFill } from "svelte/elements"
+ import posthog from "posthog-js"
let errors: { [fieldName: string]: string } = $state({})
let loading = $state(false)
@@ -61,6 +62,10 @@
await applyAction(result)
loading = false
if (result.type === "success") {
+ posthog.capture("contact_form_submitted")
+ posthog.logger.info("contact form submitted", {
+ form: "contact_us",
+ })
showSuccess = true
} else if (result.type === "failure") {
errors = result.data?.errors ?? {}
diff --git a/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(marketing)/pricing/pricing_module.svelte b/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(marketing)/pricing/pricing_module.svelte
index 1c9599e59..105e88925 100644
--- a/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(marketing)/pricing/pricing_module.svelte
+++ b/apps/basic-integration/sveltekit/CMSaasStarter/src/routes/(marketing)/pricing/pricing_module.svelte
@@ -1,5 +1,19 @@