# Nanolytica Cloud
> Privacy-first analytics for websites, mobile apps, smart TVs, and IoT devices.
Nanolytica Cloud is a private multi-tenant analytics project powered by ClickHouse. Visitor tracking does not set cookies. The dashboard uses sign-in cookies and browser storage for preferences and local AI models.
## Features
- Web tracking via a single script tag, native app tracking via HTTP API
- Real-time dashboards with WebSocket live updates
- Behavioral insights: journey analysis, conversion funnels, retention cohorts, session explorer
- Custom events via `window.Nanolytica.track(name, props, { value })`
- Goals (pageview-path or event-name) with completions, conversion rate, and revenue in the site currency
- Auto-tracking opt-ins for outbound link clicks, file downloads, and 404 pages
- Core Web Vitals (LCP, INP, CLS, FCP, TTFB) with per-page breakdown
- Advanced filter operators (eq, neq, contains, not-contains, starts-with, regex) across all 11 dimensions; AND/OR match modes
- UTM campaign tracking with all 5 standard parameters
- Dimension filtering by browser, OS, device, country, referrer, screen size
- Combined views across multiple sites
- Bot and crawler detection (55+ patterns)
- CSV export (includes goal completions section)
- Public shareable dashboards
- Local AI reports with Qwen3 4B, 1.7B or 0.6B, browser recommendations and PDF export
## Visitors Metrics
The Visitors tab includes views per anonymous visitor, page/source/country pageview shares, explicit period comparisons, traffic timing and measurement coverage. Source/country tables separate Other from Unknown. Timing uses the dashboard timezone and offers averages weighted by covered hours and calendar days; partial coverage and DST are accounted for. Its 7×24 activity table shows averages, totals and covered hours, distinguishes zero from uncovered time, and is included in CSV exports. An optional dashed chart overlay shifts previous observations forward by the interval's equal elapsed duration into current calendar buckets. Missing samples and future current buckets remain gaps; count, seconds and percentage series use separate axes. Visitors are estimates, engagement is measured page activity, and coverage describes recorded data only. Realtime is a site-wide five-minute sample-time indicator independent of filters. No additional tracking identifiers are required for these metrics.
## AI Reports
The Reports tab offers three Apache-2.0 Qwen3 models: 4B for quality (about 2.3 GB download), 1.7B for balance (about 1 GB), and 0.6B for lighter devices (about 400 MB). WebGPU inference runs in a worker. Without WebGPU, the 0.6B CPU option uses a separate download of about 640 MB.
The browser suggests a model from locally checked WebGPU capabilities, reported memory and estimated storage quota. It cannot reliably measure free GPU memory. Users can override the suggestion; their selection is remembered. Only the chosen model downloads after Load model is pressed. Storage quotas and caching vary by browser and device.
Reports follow a privacy-focused analyst prompt with an Executive Summary, Key Metrics table, Key Insights, supported acquisition/content/conversion/audience sections, investigations, recommended actions, privacy-safe measurement gaps and a Bottom Line. Observed facts, interpretations and hypotheses are distinguished. Missing comparisons, funnels or linked dimensions are not invented. Reports never recommend identifying visitors, fingerprinting or cross-site tracking. Sparse data produces shorter reports. Both runtimes use a 16K context with up to 3,000 output tokens, requiring additional memory beyond base model estimates.
Reports include pageview shares, views per visitor, and leading hours, weekdays and dates in the dashboard timezone. Timing ranks period totals, not per-day averages; partial days and unequal weekday coverage can affect ranks. Reports may suggest checking a campaign or event calendar for standout dates, but do not establish holiday or campaign causes. Model and runtime assets download from external hosts, but analytics are not sent to an AI service. Check generated claims against the dashboard before sharing.
## Tracking
### Web
Add to any page:
```html
```
### Native Apps (Mobile, TV, IoT)
POST to `/api/collect`:
```json
{
"site_id": "YOUR-SITE-UUID",
"path": "/home",
"referrer": "",
"user_agent": "MyApp/1.2.3 (iOS 17; iPhone)",
"screen_size": "390x844",
"duration_sec": 0,
"scroll_depth": 0,
"utm_source": "",
"utm_medium": "",
"utm_campaign": "",
"utm_content": "",
"utm_term": ""
}
```
Fields: `site_id` (required, UUID), `path` (max 2048), `referrer` (max 2048), `user_agent` (max 512), `screen_size` (WIDTHxHEIGHT), `duration_sec` (0-86400), `scroll_depth` (0-100), `utm_*` (max 256 each). For custom events also include `event_name` (≤ 64 chars, `^[a-zA-Z0-9_-]+$`), optional `props` (object, ≤ 10 keys), and optional `value` (number, for revenue goals).
Response: 204 No Content (accepted), 400 Bad Request (validation error), 429 Too Many Requests (rate limited).
## Privacy
- Visitor tracking does not set cookies or use localStorage
- IP addresses hashed with a per-site salt, never stored raw; the salt does not rotate daily
- Do Not Track (DNT: 1) respected, event discarded entirely
- Data retention: 365-day TTL in ClickHouse
- Dashboard sign-in cookies, preferences and model caches are separate from visitor tracking
## UTM Campaign Tracking
All 5 standard UTM parameters captured automatically from URL query strings: utm_source, utm_medium, utm_campaign, utm_content, utm_term. Also supports `ref` and `source` as aliases for utm_source. Session-level attribution (first pageview only). utm_source merges with organic referrer (UTM takes priority).
## Behavioral Insights
- **Journey**: top page-to-page transitions, entry pages, exit pages
- **Funnels**: multi-step conversion paths with drop-off tracking (ClickHouse windowFunnel)
- **Retention**: cohort grid by first-visit week/month with color-coded return rates
- **Sessions**: individual visitor sessions with page-by-page timelines
- **Performance**: Core Web Vitals (LCP, INP, CLS, FCP, TTFB) scored with Google thresholds, per-page breakdown
- **Goals**: pageview-path or event-name conversion goals with completions, unique visitors, conversion rate, and revenue total in the site's display currency
## Custom Events & Goals
Fire arbitrary events from the tracking snippet:
```js
Nanolytica.track('cta_click');
Nanolytica.track('signup', { plan: 'pro', source: 'pricing-page' });
Nanolytica.track('purchase', { plan: 'pro' }, { value: 49.99 });
```
Event name: max 64 chars, matches `^[a-zA-Z0-9_-]+$`. Props: up to 10 key/value pairs (keys ≤ 64 chars, values ≤ 256 chars). Optional numeric `value` sums into revenue. Names starting with `nanolytica_` are reserved for auto-tracking.
### Auto-tracking (opt-in)
Add `data-*` attributes to the snippet, or toggle per site under Setup → Auto-tracking:
```html
```
- `data-track-outbound` — fires `nanolytica_outbound` on clicks to different hosts (props: url, host)
- `data-track-downloads` — fires `nanolytica_file_download` on pdf/zip/csv/docx/xlsx/mp3/mp4/… (props: url, ext). Downloads win over outbound to avoid double counts.
- `data-track-404` — fires `nanolytica_404` when the page contains `` (props: path, referrer)
### Goals
Two kinds:
- **Pageview** — path match with operators `eq`, `starts_with`, `contains`, `regex`.
- **Event** — event-name match with optional prop filters (`eq`, `neq`, `contains`).
Goals show completions, unique visitors, conversion rate (against the period-filtered unique-visitor denominator), and revenue total in the site's currency (default USD; USD/EUR/GBP/JPY/CAD/AUD/TRY/INR/BRL/CHF supported). Goals respect the dashboard period selector, timezone, and active filters, and render read-only on public dashboards.
## Stack
- Go / Echo — HTTP server, auth, middleware
- ClickHouse — analytics storage (MergeTree, partitioned by month)
- SQLite — user accounts, sites, funnels, goals, per-site currency and auto-tracking flags
- templ — type-safe HTML templates
- Tailwind CSS — styling
- TypeScript — tracking script and dashboard frontend
## Links
- Website: https://cloud.nanolytica.org
- Documentation: https://cloud.nanolytica.org/documents