Analytics Integration
How v0- and Claude-built pages access the Cockpit analytics system — via MCP tools and a reusable tracking snippet.
Overview
Cockpit uses Umami as the analytics platform. Each center can configure its own Umami website ID and URL (Dashboard → Center → Analytics). External pages (v0 builds, Claude pages) can:
- Embed Umami tracking →
V0AnalyticsSnippet - Read website analytics →
cockpit_analytics_website_stats,cockpit_analytics_umami_events,cockpit_analytics_umami_export,cockpit_analytics_website_insights - Read content performance →
cockpit_analytics_content_metrics,cockpit_analytics_content_performance,cockpit_analytics_content_performance_batch,cockpit_analytics_content_performance_insights - Signage & reporting →
cockpit_analytics_signage,cockpit_analytics_reporting,cockpit_analytics_trending,cockpit_analytics_companion_stats - Capture custom events →
cockpit_analytics_track_event(Cockpit DB, not Umami)
MCP Tools (Umami & Analytics)
All analytics tools run on mcp-cockpit-os and require COCKPIT_AGENCYOS_API_KEY (Bearer). The dashboard also accepts session cookies on the same API routes.
| MCP tool | Source | Content |
|---|---|---|
cockpit_analytics_website_stats | Umami | Full: stats, series, top pages, referrers, devices, browsers, OS, countries, optional events |
cockpit_analytics_umami_events | Umami | Custom events (raw list) |
cockpit_analytics_umami_export | Umami | Multi-period 30 / 90 / 365 days |
cockpit_analytics_website_insights | Umami + AI | Website insights (traffic, bounce, bot, …) |
cockpit_analytics_content_metrics | Umami + DB | Aggregated content views |
cockpit_analytics_content_performance | Umami + DB | Single item (news/offer/event/shop/job/hotpick) |
cockpit_analytics_content_performance_batch | Umami + DB | Up to 40 items |
cockpit_analytics_content_performance_insights | Umami + AI | AI tips per item |
cockpit_analytics_signage | Signage API / Companion Umami | Stele/kiosk analytics |
cockpit_analytics_companion_stats | Umami (system-wide) | NOW!/Companion website |
cockpit_analytics_reporting | Cockpit DB | AI usage, searches, funnel |
cockpit_analytics_trending | Chatbot DB | Trending shops/offers (no Umami) |
cockpit_analytics_track_event | Cockpit DB | Write custom events (not Umami) |
Periods (period): 24h, 7d, 30d, 90d, 365d.
Discover: cockpit_mcp_discover_tools(query: "analytics").
cockpit_analytics_website_stats
Full Umami website analytics for a center.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
centerId | UUID | ✅ | Center |
period | 24h | 7d | 30d | 90d | 365d | 30d | Period |
includeEvents | boolean | false | Include Umami custom events |
metricsLimit | 1–50 | 15 | Max entries per top list |
Prerequisite: Analytics enabled,
umamiWebsiteId, serverUMAMI_PASSWORD.
Global content performance (Umami + AI)
Server modules under apps/dashboard/src/lib/analytics/ (barrel: @/lib/analytics):
| Module | Purpose |
|---|---|
center-umami-config.ts | Center analytics flags + umamiWebsiteId |
content-url-paths.ts | Public detail paths (news, offers, events, shops, jobs) |
content-umami-metrics.ts | Single fetch + UmamiUrlMetricsCache (one Umami call per center) |
content-performance-service.ts | Snapshot: views, engagement, quality |
content-performance-ai.ts | AI recommendations per item (OPENAI_API_KEY) |
HTTP (session or agency API key + center access)
| Route | Description |
|---|---|
GET /api/analytics/website-stats?centerId=&timeframe= | Full Umami website analytics |
GET /api/analytics/umami-events?centerId= | Umami custom events |
GET /api/analytics/umami-export?centerId= | Multi-period export |
GET /api/analytics/insights?centerId= | AI website insights |
GET /api/analytics/signage?centerId= | Signage/stele |
GET /api/analytics/companion-stats | Companion Umami (system-wide, API key only) |
GET /api/analytics/reporting?centerId= | Center reporting |
GET /api/analytics/trending?centerId= | Chatbot trending |
GET /api/analytics/content-performance?centerId=&kind=&id= | Performance snapshot for one item |
POST /api/analytics/content-performance/batch | Body: { centerId, items: [{ kind, id }] } — batch with shared Umami cache |
POST /api/analytics/content-performance/insights | Body: { centerId, kind, id, context? } — AI insights + snapshot |
GET /api/content/recent?centerId= | Content overview: views for all content types |
GET /api/content/metrics?centerId= | Aggregated views (Umami detail paths, 90 days) |
Requirements: UMAMI_PASSWORD on the server; center with analyticsEnabled, provider umami or both, umamiWebsiteId. Optional umamiUrl per center.
Client: Hook useContentPerformance(); UI at /dashboard/content → Content-Insights button.
kind: news | offer | event | shop | job | hotpick
Dashboard: AI insights (internal)
GET /api/analytics/insights?centerId={uuid}&timeframe=day|week|month
- Session or agency API key with center access
- Reads Umami stats + events; generates 3–5 insights via
gpt-4o-mini(OPENAI_API_KEY) - UI:
/dashboard/analytics→ teaser in Website tab + AI Insights tab
cockpit_analytics_content_metrics
Aggregated metrics for the content overview (GET /api/content/metrics): views (Umami detail paths + DB), engagement, categoryBreakdown.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
centerId | string (UUID) | ✅ | Center UUID |
Example
cockpit_analytics_content_metrics(centerId: "f1a2b3c4-...")
cockpit_analytics_content_performance
Snapshot for one item (Umami, DB, quality, engagement).
| Parameter | Type | Required | Description |
|---|---|---|---|
centerId | string (UUID) | ✅ | Center |
kind | news | offer | event | shop | job | hotpick | ✅ | Type |
id | string (UUID) | ✅ | Item ID |
cockpit_analytics_content_performance_batch
Multiple snapshots in one request (max. 40 items) — one Umami call per center. Prefer over many single GETs after cockpit_center_context.
| Parameter | Type | Required | Description |
|---|---|---|---|
centerId | string (UUID) | ✅ | Center |
items | { kind, id }[] | ✅ | 1–40 entries |
Example
cockpit_analytics_content_performance_batch(
centerId: "f1a2b3c4-...",
items: [
{ kind: "news", id: "…" },
{ kind: "offer", id: "…" }
]
)
Response (excerpt): data[] with { kind, id, data?: snapshot } or { error: "not_found"|"failed" }; meta.umamiBatch: true when Umami is active.
cockpit_analytics_content_performance_insights
AI recommendations for one item (POST, optional context).
| Parameter | Type | Required | Description |
|---|---|---|---|
centerId | string (UUID) | ✅ | Center |
kind / id | as above | ✅ | Item |
context | string | – | Extra context for AI |
cockpit_analytics_track_event
Records a custom usage event in the Cockpit DB (monthly reporting).
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
centerId | string (UUID) | ✅ | – | Center UUID |
eventType | string | ✅ | – | e.g. "offer_click" |
source | "website" | "kiosk" | "companion" | "app" | – | "website" | Event source |
metadata | object | – | – | Optional payload |
Tracking snippet for external pages
V0AnalyticsSnippet
React component (apps/center-website/components/analytics/v0-analytics-snippet.tsx) embeds Umami in v0/Claude pages.
Prerequisites
- Next.js with
next/script - Center has analytics enabled and
umamiWebsiteIdset
Props
| Prop | Type | Required | Description |
|---|---|---|---|
centerId | string | ✅ | Center UUID |
umamiWebsiteId | string | – | Optional; loaded via API if omitted |
umamiUrl | string | – | Default: https://analytics.cockpit-os.de |
Usage
import { V0AnalyticsSnippet } from '@/components/analytics/v0-analytics-snippet'
export default function Layout({ children }) {
return (
<>
<V0AnalyticsSnippet centerId="f1a2b3c4-uuid-of-center" />
{children}
</>
)
}
Behavior
- Waits for cookie consent (
vanilla-cookieconsent) - Dev: script may load without consent for testing
- Renders nothing if no website ID or analytics disabled (no error)
API endpoints
| Endpoint | Method | Auth | Description |
|---|---|---|---|
/api/analytics/website-stats | GET | Bearer | Umami traffic stats |
/api/analytics/footfall | GET | Session | Footfall (mock until live source) |
/api/analytics/usage-events | POST | Bearer | Custom events |
/api/analytics/content-performance | GET | Bearer | Snapshot per item |
/api/analytics/content-performance/batch | POST | Bearer | Multiple snapshots |
/api/analytics/content-performance/insights | POST | Bearer | AI + snapshot |
/api/analytics/insights | GET | Session | Website AI insights |
/api/content/metrics | GET | Bearer | Aggregated content metrics |
/api/content/recent | GET | Bearer | Recent content + Umami views |
/api/content/news/{id}/performance | GET/POST | Session | News SEO (POST = OpenAI) |
Public (v0, no session): GET /api/agencyos/v1/public/visitor-surface?centerId= → data.tracking for V0AnalyticsSnippet.
MCP uses COCKPIT_AGENCYOS_API_KEY as Bearer on dashboard routes.
Content overview (/dashboard/content)
GET /api/content/metrics: Views from Umami detail paths (90 days) + DB for hot picks/jobs engagement.GET /api/content/recent: One Umami top-URL call per center; path matching viacontent-url-paths.tsandcontent-umami-match-opts.ts(center slug prefix, shop chain slug, trailing slash).- Detail pages:
ContentPerformanceCard+ APIs above (news, offers, events, jobs, shops, shop locations).
Content detail: Umami shows traffic, Cockpit shows 0
Applies to all content types above. Common causes: public URL slug differs from Cockpit (e.g. shop chain slug /shops/al-carbon/ vs UUID), wrong Umami website ID, or missing UMAMI_PASSWORD. Matching uses path variants including /[centerSlug]/… and shop chain segments. Reload the Analytics tab after deploy; a match shows Umami URL.
Verification (checklist)
1. Cockpit configuration
| Check | How |
|---|---|
| Analytics on | Dashboard → Center → Analytics → enabled, provider umami or both |
umamiWebsiteId set | Same tab or center API |
| Server | UMAMI_PASSWORD on Render/dashboard |
| AI insights | OPENAI_API_KEY (optional) |
MCP: cockpit_public_visitor_surface or cockpit_get_center_website_config → data.tracking.
2. Center website (standard layout)
| Check | Expected |
|---|---|
| Script loads | DevTools → Network: script.js with data-website-id |
| Cookie consent | Accept analytics — otherwise no script |
| Pageviews | Umami UI or cockpit_analytics_website_stats |
| Detail URLs | e.g. /aktuelles/news/{slug}, /angebote/{slug} — see content-url-paths.ts |
Different paths (e.g. /nachrichten/… only): extend content-url-paths.ts in the dashboard — no template change if routes already exist.
3. External / v0 page (no app/[slug]/layout)
<V0AnalyticsSnippet centerId="<center-uuid>" />
Verify: cockpit_public_visitor_surface → data.tracking.umamiWebsiteId not empty.
4. Content performance in dashboard
| Check | API / UI |
|---|---|
| Overview loads quickly | /dashboard/content — ~12s Umami timeout max, then DB fallback |
| Views in table | Views column, optionally "(Umami)" |
| Detail page | Performance card on news/offer/event/shop/job |
| MCP aggregate | cockpit_analytics_content_metrics |
| MCP items | cockpit_analytics_content_performance or cockpit_analytics_content_performance_batch |
| MCP AI | cockpit_analytics_content_performance_insights |
5. Custom events (optional)
Website: trackEvent('offer_click', { offerId }) from umami-analytics.tsx.
MCP: cockpit_analytics_track_event → DB, not Umami pageviews.
6. Quick curl test
curl -s -H "Authorization: Bearer $COCKPIT_AGENCYOS_API_KEY" \
"https://dashboard.cockpit-os.de/api/content/metrics?centerId=<UUID>"
curl -s -X POST -H "Authorization: Bearer $COCKPIT_AGENCYOS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"centerId":"<UUID>","items":[{"kind":"news","id":"<NEWS_UUID>"}]}' \
"https://dashboard.cockpit-os.de/api/analytics/content-performance/batch"
Footfall
Dashboard: /dashboard/analytics/footfall
API: GET /api/analytics/footfall?centerId=<uuid>
Architecture
External page (v0/Claude)
│
├─► V0AnalyticsSnippet ──► Umami script
│ └─ public visitor-surface API
│
└─► cockpit_analytics_* (MCP)
├─► /api/analytics/website-stats ──► Umami API
├─► /api/content/metrics ──► Umami + Prisma
├─► /api/analytics/content-performance ──► Umami + Prisma
└─► /api/analytics/usage-events ──► Prisma
Data flow
- Page view:
V0AnalyticsSnippet→ Umami tracks directly - Custom events:
cockpit_analytics_track_event→ Cockpit DB - Read stats: MCP tools → dashboard APIs → Umami / Prisma
Related documentation
Nutzungsstatistik: Seitenaufrufe werden anonymisiert erfasst. Im Umami-Dashboard nach diesem Pfad filtern: /en/developer-guide/analytics-integration