Skip to content

feat: integrate Umami/Innblikk tracking via ResearchOps sporing script#501

Draft
rbjornstad wants to merge 6 commits into
mainfrom
feat/umami-tracking
Draft

feat: integrate Umami/Innblikk tracking via ResearchOps sporing script#501
rbjornstad wants to merge 6 commits into
mainfrom
feat/umami-tracking

Conversation

@rbjornstad

@rbjornstad rbjornstad commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds NAV's ResearchOps "sporing" tracking script to console-frontend. Privacy-first analytics (no cookies, GDPR compliant) with automatic page view tracking and custom event tracking for key user actions. Data flows through NAV's event proxy to BigQuery.

What's included

Infrastructure (opt-in per tenant)

  • tracking.enabled, tracking.websiteId, and tracking.dev Helm chart values (default: disabled)
  • Env vars TRACKING_ENABLED / TRACKING_WEBSITE_ID / TRACKING_DEV passed through hooks.server.ts → layout → client
  • Script conditionally injected in +layout.svelte onMount only when enabled
  • TRACKING_DEV=true uses sporing-dev.js (routes to dev proxy), otherwise uses production sporing.js

Privacy

  • beforeSend replaces resolved URLs with SvelteKit route IDs (e.g. /team/[team]/secrets instead of /team/nais/secrets) — gives aggregate page analytics without leaking team/app names
  • Events without a route ID are dropped entirely (returns null)
  • No user identification (sporing.identify() not used)
  • No cookies, no consent banner needed (internal ansatte tool)

Custom events tracked

Event Component Insight
favorite-add / favorite-remove AddToFavorites, FavoritesListItem Feature adoption
favorite-click FavoritesListItem Navigation usage
favorite-reorder FavoritesList Engagement
restart-app / stop-app AppActions Core operations
delete-app delete/+page Cleanup patterns
delete-team confirm_delete/+page Churn
reveal-secret ViewSecretModal Security audit
trigger-job JobActions Workflow usage
suppress-vulnerability SuppressFinding Security workflow

All events carry only the event name — no custom payload data. Page context (route ID pattern) is attached automatically by beforeSend.

New files

  • src/lib/tracking.ts — thin trackEvent() wrapper that no-ops when sporing is unavailable
  • docs/umami-integration.md — integration plan and decisions

Before merging

  • Register website in Slack #researchops and get a website-id
  • Verify events appear in Innblikk dev with local dev setup
  • Set tracking.enabled: true and tracking.websiteId in NAV tenant Helm values

References

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

Team deletion confirmation currently navigates away even when the mutation returns errors, preventing users from seeing the failure (and leaving loading state inconsistent).

Pull request overview

Integrates NAV ResearchOps “sporing” (Umami/Innblikk) analytics into console-frontend with opt-in configuration per tenant, runtime script injection, and custom event tracking for key user actions.

Changes:

  • Add Helm values and deployment env vars to enable/disable tracking and configure website ID per tenant.
  • Inject the tracking script at runtime and sanitize tracked URLs via a beforeSend hook.
  • Introduce a small tracking utility and emit custom events from favorites, workload actions, secret reveal, and vulnerability suppression flows.
File summaries
File Description
src/routes/team/[team]/settings/confirm_delete/+page.svelte Track delete-team after successful confirmation of team deletion.
src/routes/team/[team]/[env]/secret/[secret]/ViewSecretModal.svelte Track reveal-secret after successful secret reveal.
src/routes/team/[team]/[env]/job/[job]/JobActions.svelte Track trigger-job after successfully triggering a job run.
src/routes/team/[team]/[env]/app/[app]/delete/+page.svelte Track delete-app after successful application deletion.
src/routes/team/[team]/[env]/app/[app]/AppActions.svelte Track restart-app and stop-app after successful actions.
src/routes/FavoritesList.svelte Track favorite-reorder when reordering favorites.
src/routes/+layout.svelte Conditionally set up beforeSend and inject the sporing script on mount.
src/routes/+layout.server.ts Expose tracking config from event.locals to client layout data.
src/lib/ui/AddToFavorites.svelte Track favorite-add / favorite-remove with page type metadata.
src/lib/tracking.ts Add trackEvent() wrapper and pageTypeFromPath() helper.
src/lib/domain/vulnerability/SuppressFinding.svelte Track suppress-vulnerability on successful suppression.
src/lib/domain/list-items/FavoritesListItem.svelte Track favorite-click and favorite-remove with page type metadata.
src/hooks.server.ts Read TRACKING_ENABLED / TRACKING_WEBSITE_ID into event.locals.
src/app.d.ts Add global typings for window.sporing, beforeSend, and new locals.
docs/umami-integration.md Document integration plan/decisions for sporing/Umami.
charts/values.yaml Add tracking.enabled / tracking.websiteId values (default disabled).
charts/templates/deployment.yaml Pass tracking env vars into the container.
charts/Feature.yaml Expose tracking values in the chart feature configuration.

Copilot's findings

  • Files reviewed: 17/18 changed files
  • Comments generated: 3

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread src/routes/team/[team]/settings/confirm_delete/+page.svelte Outdated
Comment thread src/routes/+layout.svelte Outdated
Comment thread docs/umami-integration.md Outdated
@rbjornstad rbjornstad force-pushed the feat/umami-tracking branch 2 times, most recently from 9f9a600 to 6d2a227 Compare June 19, 2026 11:09

@rbjornstad rbjornstad left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed all review comments in 7071670.

@rbjornstad rbjornstad left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed review comments.

Comment thread src/routes/team/[team]/settings/confirm_delete/+page.svelte
Comment thread docs/umami-integration.md

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

The current beforeSend implementation can fall back to sending resolved URLs when route.id is missing, and the Helm Feature config/docs have small but concrete mismatches that should be corrected.

Copilot's findings
  • Files reviewed: 17/18 changed files
  • Comments generated: 4

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread src/routes/+layout.svelte Outdated
Comment thread charts/Feature.yaml
Comment thread docs/umami-integration.md
Comment thread docs/umami-integration.md Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

Two issues in the new tracking plumbing can drop events or misclassify pageType, reducing the correctness of the analytics this PR is meant to provide.

Copilot's findings
  • Files reviewed: 17/18 changed files
  • Comments generated: 2

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread src/lib/tracking.ts Outdated
Comment thread src/routes/+layout.svelte

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

It currently risks sending environment slugs via pageTypeFromPath() and may emit a delete-team event even when the mutation result indicates deletion didn’t start.

Copilot's findings
  • Files reviewed: 17/18 changed files
  • Comments generated: 2

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread src/lib/tracking.ts Outdated
Comment thread src/routes/team/[team]/settings/confirm_delete/+page.svelte
@rbjornstad rbjornstad force-pushed the feat/umami-tracking branch 2 times, most recently from e8d84ff to 7431295 Compare June 19, 2026 13:06
@rbjornstad rbjornstad requested a review from Copilot June 19, 2026 13:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

There are verified inconsistencies between the stated tracking payload/documentation/PR description and the implemented tracking helper + event payload shape that should be reconciled before merging.

Copilot's findings
  • Files reviewed: 17/18 changed files
  • Comments generated: 3

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread src/lib/tracking.ts
Comment thread docs/umami-integration.md Outdated
Comment thread src/lib/ui/AddToFavorites.svelte

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

The documentation currently contains an event-name mismatch (suppress-finding vs suppress-vulnerability) that should be corrected before merge to avoid inconsistent analytics naming.

Copilot's findings
  • Files reviewed: 17/18 changed files
  • Comments generated: 2

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread docs/umami-integration.md
Comment thread src/lib/tracking.ts
@rbjornstad rbjornstad force-pushed the feat/umami-tracking branch from b619c04 to 8f70e94 Compare June 19, 2026 13:45
- Add tracking.enabled and tracking.websiteId to Helm chart (opt-in per tenant)
- Pass tracking config through hooks.server.ts → layout server → layout client
- Conditionally inject sporing.js script in +layout.svelte onMount
- Add beforeSend function to strip query params from tracked URLs
- Create src/lib/tracking.ts utility with trackEvent() wrapper
- Track favourites: add, remove, click, reorder (with pageType)
- Track app actions: restart, stop, delete
- Track team deletion, secret reveal, job trigger, vulnerability suppress
- Add window.sporing TypeScript declarations in app.d.ts
- Add integration plan in docs/umami-integration.md
- Replace resolved URLs (e.g. /team/nais/secrets) with SvelteKit route IDs
  (e.g. /team/[team]/secrets) in beforeSend for aggregate page analytics
- Add TRACKING_DEV flag to switch between sporing.js and sporing-dev.js
- Update afterNavigate to keep route ID in sync for the sporing script
- Gate goto on success in confirm_delete (don't navigate on error, reset loading)
- Update docs/umami-integration.md to match onMount implementation
@rbjornstad rbjornstad force-pushed the feat/umami-tracking branch from 8f70e94 to 16aa91c Compare June 25, 2026 07:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants