From 0c3b4993d9a5b21e67169f417e52377b38ba516c Mon Sep 17 00:00:00 2001 From: iza <59828082+izadoesdev@users.noreply.github.com> Date: Mon, 5 Oct 2026 00:31:47 +0300 Subject: [PATCH 1/3] feat(dashboard): show interaction tracking as on by default and say what it finds The tracker now tracks interactions unless told not to, so snippets omit the option by default and write data-track-interactions="false" only when a site turns it off. The setting describes rage clicks, dead clicks and abandoned forms instead of button clicks. --- .../_components/constants/settings-constants.ts | 9 +++++++-- .../[id]/_components/utils/code-generators.test.ts | 14 ++++++++++++++ .../[id]/_components/utils/code-generators.ts | 2 +- .../[id]/_components/utils/tracking-defaults.ts | 2 +- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/apps/dashboard/app/(main)/websites/[id]/_components/constants/settings-constants.ts b/apps/dashboard/app/(main)/websites/[id]/_components/constants/settings-constants.ts index 7ca367bf12..75737e878a 100644 --- a/apps/dashboard/app/(main)/websites/[id]/_components/constants/settings-constants.ts +++ b/apps/dashboard/app/(main)/websites/[id]/_components/constants/settings-constants.ts @@ -69,8 +69,13 @@ export const BASIC_TRACKING_OPTIONS: TrackingOptionConfig[] = [ { key: "trackInteractions", title: "Interactions", - description: "Track button clicks and form submissions", - data: ["Element clicked", "Form submissions"], + description: + "See where visitors get stuck: rage clicks, dead clicks, and forms they abandon", + data: [ + "Rage and dead clicks", + "Clicked element labels, never text", + "Form fields touched and submitted", + ], }, ]; diff --git a/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.test.ts b/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.test.ts index 2bdac99956..be4205460e 100644 --- a/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.test.ts +++ b/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.test.ts @@ -69,6 +69,20 @@ assert.ok(prompt.includes("## Common issues")); expect(npm).not.toContain("trackSessions"); }); + it("leaves interaction tracking to the default and writes it out only when turned off", () => { + const off = { ...RECOMMENDED_DEFAULTS, trackInteractions: false }; + + expect( + generateScriptTag("example-client-id", RECOMMENDED_DEFAULTS) + ).not.toContain("track-interactions"); + expect(generateScriptTag("example-client-id", off)).toContain( + 'data-track-interactions="false"' + ); + expect(generateNpmCode("example-client-id", off)).toContain( + "trackInteractions={false}" + ); + }); + it("asks for optional install feedback without code or secrets, and only names real options", () => { const prompt = generateAgentPrompt("example-client-id"); diff --git a/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.ts b/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.ts index 4bc7726157..f714f9368e 100644 --- a/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.ts +++ b/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.ts @@ -72,7 +72,7 @@ Page views and sessions are automatic. Turn on the rest based on what the codeba | trackWebVitals | Always. Powers the Web Vitals page (LCP, CLS, INP, TTFB). | | trackErrors | Always for apps with client-side JavaScript. Powers the Errors page. | | trackOutgoingLinks | Marketing sites, docs, link-heavy pages. Records clicks that leave the site. | -| trackInteractions | Apps with buttons and forms worth counting without custom events. | +| trackInteractions | On by default (rage clicks, dead clicks, form drop-off). Set it to false only where the site owner does not want click analytics. | | trackAttributes | When you add data-track attributes to elements instead of calling track(). | | trackHashChanges | Single-page apps that route with the URL hash. | | skipPatterns | Admin, internal, or preview routes that should never be recorded, e.g. ["/admin/**"]. | diff --git a/apps/dashboard/app/(main)/websites/[id]/_components/utils/tracking-defaults.ts b/apps/dashboard/app/(main)/websites/[id]/_components/utils/tracking-defaults.ts index 97b7b56aba..ce2cee7099 100644 --- a/apps/dashboard/app/(main)/websites/[id]/_components/utils/tracking-defaults.ts +++ b/apps/dashboard/app/(main)/websites/[id]/_components/utils/tracking-defaults.ts @@ -7,7 +7,7 @@ export const ACTUAL_LIBRARY_DEFAULTS: TrackingOptions = { trackAttributes: false, trackOutgoingLinks: false, - trackInteractions: false, + trackInteractions: true, trackWebVitals: false, trackErrors: false, From 57d7aea314ce67ae5ec9c933d90d31cdcbebc59f Mon Sep 17 00:00:00 2001 From: iza <59828082+izadoesdev@users.noreply.github.com> Date: Mon, 5 Oct 2026 12:32:13 +0300 Subject: [PATCH 2/3] fix(dashboard): preserve interactions for pinned tracker scripts --- .../_components/utils/code-generators.test.ts | 36 ++++++++++++++++++- .../[id]/_components/utils/code-generators.ts | 4 +++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.test.ts b/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.test.ts index be4205460e..794ed9d996 100644 --- a/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.test.ts +++ b/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.test.ts @@ -3,6 +3,7 @@ import { generateAgentPrompt, generateNpmCode, generateScriptTag, + generateVueCode, } from "./code-generators"; import { RECOMMENDED_DEFAULTS } from "./tracking-defaults"; @@ -69,7 +70,7 @@ assert.ok(prompt.includes("## Common issues")); expect(npm).not.toContain("trackSessions"); }); - it("leaves interaction tracking to the default and writes it out only when turned off", () => { + it("leaves current-runtime interactions to the default and writes an explicit opt-out", () => { const off = { ...RECOMMENDED_DEFAULTS, trackInteractions: false }; expect( @@ -81,6 +82,39 @@ assert.ok(prompt.includes("## Common issues")); expect(generateNpmCode("example-client-id", off)).toContain( "trackInteractions={false}" ); + expect( + generateNpmCode("example-client-id", RECOMMENDED_DEFAULTS) + ).not.toContain("trackInteractions"); + expect( + generateVueCode("example-client-id", RECOMMENDED_DEFAULTS) + ).not.toContain("track-interactions"); + expect(generateVueCode("example-client-id", off)).toContain( + ':track-interactions="false"' + ); + }); + + it.each([ + true, + false, + ])("keeps explicit interactions=%s for immutable pinned bundles", (trackInteractions) => { + const versionedScript = { + filename: "databuddy.v1.js", + sriHash: "sha384-example", + version: 1, + }; + const script = generateScriptTag( + "example-client-id", + { ...RECOMMENDED_DEFAULTS, trackInteractions, samplingRate: 0.5 }, + versionedScript + ); + + expect(script).toContain(`/${versionedScript.filename}"`); + expect(script).toContain(`integrity="${versionedScript.sriHash}"`); + expect(script).toContain(`data-track-interactions="${trackInteractions}"`); + expect(script).toContain('data-track-web-vitals="true"'); + expect(script).toContain('data-sampling-rate="0.5"'); + expect(script).not.toContain("data-enable-batching"); + expect(script).not.toContain("data-track-attributes"); }); it("asks for optional install feedback without code or secrets, and only names real options", () => { diff --git a/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.ts b/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.ts index f714f9368e..f14188aeb3 100644 --- a/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.ts +++ b/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.ts @@ -342,6 +342,10 @@ export function generateScriptTag( const dataAttrs = Object.entries(trackingOptions) .filter(([key, value]) => { + // Pinned bundles can predate the default-on behavior. + if (versionedScript && key === "trackInteractions" && value === true) { + return true; + } const actualDefault = ACTUAL_LIBRARY_DEFAULTS[key as keyof TrackingOptions]; if (value === actualDefault) { From 9845e4488d96481e40ff07292060efa88fcf328c Mon Sep 17 00:00:00 2001 From: iza <59828082+izadoesdev@users.noreply.github.com> Date: Sun, 11 Oct 2026 12:06:50 +0300 Subject: [PATCH 3/3] refactor(dashboard): name the pinned-bundle interactions rule instead of commenting it --- .../websites/[id]/_components/utils/code-generators.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.ts b/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.ts index f14188aeb3..65d19f78b6 100644 --- a/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.ts +++ b/apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.ts @@ -342,8 +342,9 @@ export function generateScriptTag( const dataAttrs = Object.entries(trackingOptions) .filter(([key, value]) => { - // Pinned bundles can predate the default-on behavior. - if (versionedScript && key === "trackInteractions" && value === true) { + const pinnedBundleNeedsInteractionsOn = + versionedScript && key === "trackInteractions" && value === true; + if (pinnedBundleNeedsInteractionsOn) { return true; } const actualDefault =