Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 40 additions & 5 deletions docs-mintlify/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"guides/apps/authentication/jwts",
"guides/apps/authentication/sign-up-rules",
"guides/apps/authentication/cli-authentication",
"guides/apps/authentication/fraud-protection",
{
"group": "All Auth Providers",
"root": "guides/apps/authentication/auth-providers",
Expand All @@ -101,9 +102,39 @@
}
]
},
"guides/apps/emails/overview",
"guides/apps/payments/overview",
"guides/apps/analytics/overview",
{
"group": "Emails",
"icon": "/images/app-icons/emails.svg",
"pages": [
"guides/apps/emails/overview",
"guides/apps/emails/sent",
"guides/apps/emails/drafts",
"guides/apps/emails/templates",
"guides/apps/emails/email-settings"
]
},
{
"group": "Payments",
"icon": "/images/app-icons/payments.svg",
"pages": [
"guides/apps/payments/overview",
"guides/apps/payments/product-lines",
"guides/apps/payments/products-and-items",
"guides/apps/payments/customers",
"guides/apps/payments/transactions",
"guides/apps/payments/settings"
]
},
{
"group": "Analytics",
"icon": "/images/app-icons/analytics.svg",
"pages": [
"guides/apps/analytics/overview",
"guides/apps/analytics/tables",
"guides/apps/analytics/queries",
"guides/apps/analytics/replays"
]
},
{
"group": "Teams",
"icon": "/images/app-icons/teams.svg",
Expand All @@ -112,7 +143,6 @@
"guides/apps/teams/team-selection"
]
},
"guides/apps/fraud-protection/overview",
"guides/apps/rbac/overview",
"guides/apps/api-keys/overview",
"guides/apps/data-vault/overview",
Expand Down Expand Up @@ -230,5 +260,10 @@
"settings": {
"customScripts": ["/apps-sidebar-filter.js", "/code-language-labels.js"]
},
"redirects": []
"redirects": [
{
"source": "/guides/apps/fraud-protection/overview",
"destination": "/guides/apps/authentication/fraud-protection"
}
]
}
119 changes: 42 additions & 77 deletions docs-mintlify/guides/apps/analytics/overview.mdx
Original file line number Diff line number Diff line change
@@ -1,112 +1,77 @@
---
title: "Analytics"
title: "Overview"
description: "Explore events, session replays, and SQL queries in your project's analytics dataset"
icon: "/images/app-icons/analytics.svg"
---

The Analytics app gives you direct access to your project's analytics dataset in Stack Auth. You can inspect raw event tables, run ClickHouse SQL queries, and watch session replays to debug real user behavior.
The Analytics app gives you direct access to your project's analytics dataset in Stack Auth. You can inspect raw event tables, run ClickHouse SQL queries, ask an AI to write queries for you, and watch session replays to debug real user behavior.

## Overview
## Pages

Analytics is organized into three areas in the dashboard:
Analytics is organized into three pages in the dashboard, each documented separately:

- **Tables**: Browse event rows with sorting, search, and incremental loading
- **Queries**: Run and save reusable ClickHouse SQL queries
- **Replays**: Watch session replays and filter by user, team, duration, activity window, and click count
<CardGroup cols={3}>
<Card title="Tables" icon="table" href="/guides/apps/analytics/tables">
Browse rows from any of your project's analytics tables, with sorting, AI-assisted search, and incremental loading.
</Card>
<Card title="Queries" icon="code" href="/guides/apps/analytics/queries">
Write, run, and save reusable ClickHouse SQL queries in folders.
</Card>
<Card title="Replays" icon="play" href="/guides/apps/analytics/replays">
Watch session replays and filter by user, team, duration, last activity, and click count.
</Card>
</CardGroup>

## How Analytics Works

Stack records analytics events and replay chunks, then exposes them through the Analytics app for read-only querying and investigation.

User activity in your app flows into Stack event ingestion, which stores data in ClickHouse. This data powers the Tables view, the SQL query runner, and the Session replay UI.
User activity in your app flows into Stack's ingestion pipeline, which stores data in ClickHouse. This dataset powers all three pages.

### What Gets Tracked

Stack collects both client-side and server-side analytics events:

- **Client-side events**: browser interaction events like `$page-view` and `$click`
- **Server-side events**: currently `$token-refresh` and `$sign-up-rule-trigger`
- **Client-side events** (captured automatically by `StackClientApp`):
- `$page-view`
- `$click`
- **Server-side events** (captured automatically by the backend):
- `$token-refresh`
- `$sign-up-rule-trigger`

Session replays are recorded as separate `rrweb` chunks tied to the same session/user as the events. Replay recording is **opt-in** — see the [Replays page](/guides/apps/analytics/replays#enabling-replay-recording-in-the-sdk) for SDK setup.

## Enabling the Analytics App

To use analytics in your project:
To use Analytics in your project:

1. Open your Stack Auth dashboard
2. Go to **Apps**
3. Open **Analytics**
4. Click **Enable**

Once enabled, the Analytics app gains a sidebar entry with three sub-pages: **Tables**, **Queries**, and **Replays**.

## Quick Start

1. Enable Analytics in your Stack Auth dashboard (**Apps -> Analytics**)
2. Initialize Stack Auth on your frontend with `StackClientApp`/`StackProvider`
1. Enable Analytics in your Stack Auth dashboard (**Apps Analytics**)
2. Initialize Stack Auth on your frontend with `StackClientApp` / `StackProvider`
3. Sign in with a real user session
4. Open the app and navigate/click around
5. Check **Analytics -> Tables** to confirm events are arriving

After setup, Stack automatically captures client-side `$page-view` and `$click` events.

If you want replay recordings, also enable `analytics.replays.enabled` in your client app config.

## Tables

The **Tables** screen is the fastest way to inspect recent analytics records.

- Currently shows the `events` table
- Built-in ordering and client-side search
- Relative/absolute timestamp display toggle
- Row detail dialog for inspecting full JSON payloads

Use this view when you need to quickly answer "what just happened?" without writing SQL.

## Queries

The **Queries** screen is a ClickHouse SQL workspace for deeper analysis.

- Run read-only SQL queries with a timeout budget
- Query the users and analytics tables
- Save reusable queries into folders
- Re-run saved queries with one click
- Edit and overwrite saved query definitions

## Session Replays

The **Replays** screen helps you move from "an event happened" to "what the user actually saw."

- Filter sessions by user, team, duration, recency, and click count
- Play back multi-tab sessions
- Control playback speed
- Optionally skip inactive ranges
- Jump across click/page-view timeline markers

Use replays when metrics alone are not enough to explain user behavior.
4. Open the app and navigate / click around
5. Check **Analytics → Tables** to confirm events are arriving

### Enabling Replay Recording in the SDK
After setup, Stack automatically captures `$page-view` and `$click` events from the browser. If you also want session replay recordings, enable `analytics.replays.enabled` in your client app config — see [Enabling Replay Recording](/guides/apps/analytics/replays#enabling-replay-recording-in-the-sdk).

Session replay recording is disabled by default. To enable it, pass `analytics.replays.enabled: true` when creating your client app.
## Usage and Quotas

```ts
import { StackClientApp } from "@stackframe/stack";
Both analytics events and session replays count against your plan's monthly quotas. The Analytics pages show inline warning banners when you approach or hit your limits:

export const stackClientApp = new StackClientApp({
projectId: process.env.NEXT_PUBLIC_STACK_PROJECT_ID!,
publishableClientKey: process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY!,
tokenStore: "nextjs-cookie",
analytics: {
replays: {
enabled: true,
// Optional. Defaults to true.
maskAllInputs: true,
},
},
});
```
- **Analytics events** — banner appears at ≥80% usage; turns into a destructive banner with no further events being tracked at 100%. Free and Team plans show an **Upgrade plan** button.
- **Session replays** — banner appears at ≥80% usage; new replays stop being recorded at 100%. Limits reset monthly.

`maskAllInputs` defaults to `true`, so form fields are masked unless you explicitly disable it.
Both banners disappear automatically when usage drops back below 80% (e.g. at the start of a new billing month).

## Best Practices

1. **Use Tables for quick incident triage**: the Tables UI is the fastest way to inspect recent `events` rows without writing SQL.
2. **Use Queries for repeatable analysis**: save important SQL in folders, and scope queries with filters/`LIMIT` so they stay within result and timeout limits.
3. **Use Replays for behavioral debugging**: start from an event pattern, then inspect matching session replays to understand what users actually did.
4. **Keep replay privacy defaults on**: leave `maskAllInputs` enabled unless you have a specific reason and a data-handling policy for unmasked inputs.
1. **Use Tables for quick triage** — pick a table from the sidebar and scan recent rows. Use AI search for one-off "what just happened?" questions.
2. **Use Queries for repeatable analysis** — save important SQL in folders with descriptions, and scope queries with `WHERE` / `LIMIT` so they stay within result and timeout limits.
3. **Use Replays for behavioral debugging** — start from an event pattern in Tables / Queries, then jump to matching session replays to see what users actually did.
4. **Keep replay privacy defaults on** — leave `maskAllInputs` enabled unless you have an explicit need for unmasked input recording and a data-handling policy to match.
5. **Watch the usage banners** — analytics events and replays are metered; if you see the 80% banner, either upgrade or scope down your recording (e.g. gate `analytics.replays.enabled` behind a sampling check).
89 changes: 89 additions & 0 deletions docs-mintlify/guides/apps/analytics/queries.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
title: "Queries"
description: "Write, run, and save reusable ClickHouse SQL queries"
sidebarTitle: "Queries"
---

The **Queries** page is a ClickHouse SQL workspace for deeper analysis and reusable reporting. It lives at **Analytics → Queries** in the dashboard sidebar.

Use it when you need to write your own SQL, share named queries with your team, or build a library of repeatable reports.

## Editor

The right pane is a freeform SQL editor:

- **Run** button — execute the current SQL (also bound to `Cmd+Enter` / `Ctrl+Enter`)
- **Save** — overwrite the currently selected saved query (preserves name and description)
- **Save As…** — save the current SQL as a new query into a folder
- **New Query** (sidebar) — clear the editor and selection to start a fresh query

Queries run with a **30-second timeout** budget. Results stream back as a virtualized table; click any row for the same **Row Details** dialog as the [Tables](/guides/apps/analytics/tables) page.

Any read-only ClickHouse SQL is accepted. You can query the same 12 tables documented on the [Tables page](/guides/apps/analytics/tables#tables-sidebar), all under the `default` schema (e.g. `default.events`, `default.users`).

### Example

```sql
SELECT * FROM default.events
ORDER BY event_at DESC
LIMIT 100
```

## Saved queries

The left sidebar contains folders of saved queries. Each saved query stores:

- **Display name**
- **SQL**
- **Description** (optional)

Click a saved query to load it into the editor and run it immediately. The selected query is highlighted in blue.

### Folder management

- **New folder** (`+` button next to **Folders**) — create a new folder by name
- **Delete folder** (trash icon, shown on hover) — delete a folder and all queries inside it (confirmation required)
- Folders are ordered by `sortOrder`, assigned automatically on creation

### Query management

- **Save As…** opens a dialog with:
- **Name** (required)
- **Folder** — pick an existing folder, or choose **Create new…** to open the folder creation dialog inline
- **Description** (optional)
- **Save** updates the SQL of the currently loaded query in-place. Use this after editing a previously saved query.
- **Delete query** (trash icon on hover) — delete a single saved query (confirmation required)

Saved queries are stored in your project's **environment config** under `analytics.queryFolders.<folderId>.queries.<queryId>` and persist across dashboard sessions.

### Loading a query

Clicking a saved query:

1. Loads its SQL into the editor
2. Runs the query immediately
3. Marks it as the current selection so the **Save** button overwrites this query in place

To stop editing a saved query and start fresh, click **New Query** in the sidebar.

## Result states

The right pane handles five distinct states:

| State | When it shows | Notes |
| --------------- | -------------------------------------------- | ----------------------------------------------------- |
| **Empty** | No query has been run yet | Shows an example query |
| **Loading** | Query is in flight | Spinner with "Running query..." |
| **Error** | ClickHouse returned an error | Shows the error message and a **Retry** button |
| **No results** | Query ran successfully but returned 0 rows | Shows "Query executed successfully but returned no rows." |
| **Results** | Query returned ≥1 row | Virtualized table with row count and click-to-inspect rows |

## Keyboard shortcuts

| Shortcut | Action |
| ------------------------- | -------------------- |
| `Cmd+Enter` / `Ctrl+Enter` | Run the current SQL |

## Limits

The analytics events usage banner appears at the top of the Queries page when your project is at ≥80% of its monthly event quota — see [Usage and Quotas](/guides/apps/analytics/overview#usage-and-quotas).
Loading
Loading