Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
23d9218
[chore] Generate v0.13
May 22, 2026
e0fe29d
Update to v0.13.0-dev
May 22, 2026
d97fe51
0.13.0 doc updates
stacy-qqq May 22, 2026
05cf959
Merge remote-tracking branch 'origin/doc-updates-0-13-0' into create-…
niedzielski May 22, 2026
687e2aa
fix build
niedzielski May 22, 2026
541e497
set default version to 0.13
niedzielski May 22, 2026
db6cbe6
fix default changelog
niedzielski May 22, 2026
9cf8d6e
Update changelog with Reddit API changes and removals
stacy-qqq May 23, 2026
4b04ad9
try symlink
niedzielski May 23, 2026
f4ef49e
Revert "try symlink"
niedzielski May 23, 2026
6539bae
Update changelog with Reddit API changes
stacy-qqq May 23, 2026
06de4d5
assets/analytics folder
stacy-qqq May 23, 2026
63918bc
Added assets/analytics folder
stacy-qqq May 23, 2026
9b50fb9
Add files via upload
stacy-qqq May 23, 2026
4b0f594
Added assets/notifications folder
stacy-qqq May 23, 2026
86261ef
Add files via upload
stacy-qqq May 23, 2026
528ea27
Add files via upload
stacy-qqq May 23, 2026
a46ebd4
Add Analytics and Notifications categories to sidebar
stacy-qqq May 23, 2026
c4d87b9
Adding analytics folder to capabilities
stacy-qqq May 23, 2026
7424c9e
Add overview for Devvit Journeys telemetry feature
stacy-qqq May 23, 2026
4b474de
copied Devvit Journeys telemetry feature
stacy-qqq May 23, 2026
abc57f1
Fix JSON syntax for Analytics and Notifications categories
stacy-qqq May 23, 2026
f69f6ec
Added notifications folder to capabilities.
stacy-qqq May 23, 2026
bc2dc81
Add push notifications overview documentation
stacy-qqq May 23, 2026
e7602b8
Create push notification best practices guide
stacy-qqq May 23, 2026
9bd4bfd
Fix links in changelog
stacy-qqq May 23, 2026
12792b8
Create guide for logged-out user experience in games
stacy-qqq May 23, 2026
ce49f97
Add sidebar entry for Building for Logged Out Players
stacy-qqq May 23, 2026
261cc7c
Formatting
stacy-qqq May 23, 2026
fb4b1f9
Formatting
stacy-qqq May 23, 2026
14aca61
Edited migration guide for PRAW to Devvit Web
stacy-qqq May 23, 2026
0840a97
Formatting
stacy-qqq May 23, 2026
0ba7c2c
Formatting
stacy-qqq May 23, 2026
702a9aa
Formatting
stacy-qqq May 23, 2026
6f83acd
Formatting
stacy-qqq May 23, 2026
a211093
Formatting
stacy-qqq May 23, 2026
39207b5
Formatting
stacy-qqq May 23, 2026
351a1f5
Formatting
stacy-qqq May 23, 2026
e7fef18
Formatting
stacy-qqq May 23, 2026
5b2c22d
Formatting
stacy-qqq May 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Binary file modified .yarn/install-state.gz
Binary file not shown.
Binary file added docs/assets/analytics/engagement-analytics.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/assets/analytics/engagement.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/analytics/journeys-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/analytics/journeys-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/analytics/journeys-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/analytics/journeys-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/analytics/login-screen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/analytics/syllo-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/analytics/syllo-play-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/analytics/syllo-sharesheet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/notifications/component-examples.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/notifications/layer-urgency.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/notifications/syllo-pn-examples.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/notifications/tangible-benefits.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/notifications/visible-progress.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions docs/capabilities/analytics/analytics-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Overview

Devvit Journeys is an experimental telemetry feature that captures the full lifecycle of a gameplay session. It provides visibility into how players enter, progress through, abandon, and complete experiences within your game.

This data can help identify friction points, analyze player behavior, inform product decisions, and surface opportunities to improve onboarding, progression, and overall engagement.

## Beta requirements

Devvit Journeys is a **gated beta**, which means that you’ll need to apply to unlock the ability to use it in your app. Current eligibility is aimed at established, already-engaged games rather than brand-new launches, and push notification partners are selected from active games with traction and predictable cadence. Check out our [featured games](https://www.reddit.com/r/GamesOnReddit/comments/1rydlny/games_launchpad/) to get an idea of what we’re looking for.

## How to apply

If you meet the beta requirements, fill out [this form](https://docs.google.com/forms/d/e/1FAIpQLScB3eXHVCBf3kyHueyf3G_raxH9_BsCGiXyGjQOOmPxWz6fEg/viewform?usp=publish-editor) for consideration, and be sure to include:

- The app identifier.
- Your push notification copy. We’ll do a quick review to ensure that it complies with our [Reddit Rules](https://redditinc.com/policies/reddit-rules).

Note that spaces are limited, and not all apps that meet the criteria will be accepted.
233 changes: 233 additions & 0 deletions docs/capabilities/analytics/devvit-journeys.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
# Devvit Journeys

Devvit Journeys adds a telemetry stream to your app that tracks the entire lifecycle of a user session. With journeys, you can:

- Boost your game’s visibility and reach through richer gameplay insights.
- Make design and feature decisions based on real user data.
- Identify friction points and optimize for better user retention.

A journey has a defined start and end point. Progress is tracked throughout and ends with a completion status. You can also attach optional game-specific data (like win/loss results or scores) at the end.

:::note
This is currently an experimental feature, and you'll need to [apply](https://docs.google.com/forms/d/e/1FAIpQLScB3eXHVCBf3kyHueyf3G_raxH9_BsCGiXyGjQOOmPxWz6fEg/viewform?usp=publish-editor) for a spot in our beta program to implement Devvit Journeys.
:::

## Journey map

A journey map is a structured, instrumented flow that tracks a player’s progression through a specific experience in your game. Think of your journey map as a series of checkpoints (events) in your game, with:

- A clear **start condition** (e.g., game begins)
- Defined **end conditions** (e.g., game ends, player quits, or player fails)
- Optional **metadata** you can attach along the way (score, outcome, time spent, etc.)

All journey maps must be reviewed and approved prior to activation to ensure they align with Reddit’s platform guidelines.

## Core events and API structure

The SDK provides a telemetry client via `@devvit/analytics/client/reddit`.

### Events

All events sent from the client are forwarded to the server, where they are enriched with standard metadata (such as app, installation, user, and post context) before being emitted as analytics events. You should set each event to fire with the corresponding trigger.

| Event Type | Trigger | Required Fields | Optional Fields |
| ------------------------- | ----------------------------------------------------------------- | -------------------- | --------------------------------- |
| **`App.Ready`** | Fire when the game has finished loading and is interactive. | None | None |
| **`Journey.Start`** | Fire when the user explicitly begins a session (not on app load). | None | None |
| **`Journey.Progress`** | Fire when the user reaches a meaningful milestone. | `progress` (0.0–1.0) | `action`, `actionDetails` |
| **`Journey.Interaction`** | Fire for granular, stateless user interactions. | `action` | `actionDetails` |
| **`Journey.End`** | Fire when the session concludes. | None | `complete`, `game { win, score }` |

### Journey ID handling

The client automatically manages the `journeyId`. You do **not** need to pass it to any method.

- A journey ID is generated server-side when `startJourney()` is called
- The client stores it in `sessionStorage` for the duration of the browser session
- Calls to `progress()`, `interaction(),` and `end()` automatically include the active journey ID

### Auto-start behavior

If `progress()` or `interaction()` is called before a journey has started, the client will automatically start a new journey.

### Ending a journey

Calling `endJourney()`:

- Sends a `Journey.End` event
- Clears the stored journey ID from `sessionStorage`

This allows a new journey to begin within the same session.

## Game-specific use cases

This example shows how a simple word game session can be represented as a Journey using four key events: `app.ready`, `journey.start`, `journey.interaction`, and `journey.end`. Together, these events capture the full lifecycle of a single play session, from when the game finishes loading to when the player completes the puzzle.

The screenshots illustrate a typical flow:

1. The game loads and signals it’s ready (`app.ready`).

![Journeys-1](../../assets/analytics/journeys-1.png)

2. The player begins playing a new word challenge (`journey.start`).

![Journeys-2](../../assets/analytics/journeys-2.png)

3. The player pauses mid-game (`journey.interaction`).

![Journeys-3](../../assets/analytics/journeys-3.png)

4. The player completes the puzzle (`journey.end`).

![Journeys-4](../../assets/analytics/journeys-4.png)

By instrumenting these moments, you can track session boundaries, understand player behavior during gameplay, and measure completion outcomes for the word game experience. See more example scenarios below.

### Scenario 1: standard level-based game

| Step | Player Action | Event Fired | Notes |
| :---: | ------------------------------------- | ----------------------- | ----------------------------- |
| **1** | Game loads | **App.Ready** | Game is fully interactive |
| **2** | Player clicks “Start Game” | **Journey.Start** | Begins a new session |
| **3** | Player completes Level 1 (of 5 levels) | **Journey.Progress** | `progress: 0.2` |
| **4** | Player opens inventory | **Journey.Interaction** | `action: "menu_opened"` |
| **5** | Player completes Level 2 | **Journey.Progress** | `progress: 0.4` |
| **6** | Player reaches final level | **Journey.Progress** | `progress: 0.9` |
| **7** | Player defeats final boss | **Journey.End** | `complete: true`, `win: true` |

### Scenario 2: player fails mid-game

| Step | Player Action | Event Fired | Notes |
| :---: | ---------------------------- | -------------------- | ------------------------------- |
| **1** | Game loads | **App.Ready** | Game is fully interactive |
| **2** | Player clicks “Start Game” | **Journey.Start** | Begins a new session |
| **3** | Player completes early level | **Journey.Progress** | `progress: 0.3` |
| **4** | Player dies | **Journey.End** | `complete: false`, `win: false` |

### Scenario 3: early exit / abandonment

| Step | Player Action | Event Fired | Notes |
| :---: | -------------------------- | ----------------------- | ------------------------- |
| **1** | Game loads | **App.Ready** | Game is fully interactive |
| **2** | Player clicks “Start Game” | **Journey.Start** | Begins a new session |
| **3** | Player pauses | **Journey.Interaction** | `action: "pause_clicked"` |
| **4** | Player quits game | **Journey.End** | `complete: false` |

## Guidelines

To ensure the integrity and quality of the telemetry stream, developers must follow these guidelines.

The platform may enforce validation checks to detect anomalous or exploitative event patterns. Failure to comply may result in delayed app approval or, in severe cases, removal from the platform.

### Event triggering

Events must reflect **intentional, committed user actions**.

- **Trigger on final commitment**.

- Fire events only after a user has completed an action.
- For interactions, this typically means using `mouseUp` or `touchEnd` (not initial input).

- **Avoid passive triggers**
- Do not track views as journeys.
- Do not use `Journey.Start` to record page or app views.
- `Journey.Start` must represent an explicit user action (like pressing “Play”)
- **Do not fire on pre-commitment input**
- Avoid early input events such as `mouseDown` or `touchStart`
- These interactions may be accidental or canceled before completion

### App allowlist

Telemetry is restricted by a server-side allowlist. Only approved apps can emit journey events. Requests from non-allowlisted apps will get a message that the event was dropped.

### Platform constraints

- **Devvit Web only**: Telemetry is only supported in Devvit Web apps (WebView).
- **Privacy**: Do **not** include PII (Personally Identifiable Information) in any user-defined fields (including `action` and `actionDetails`). You are responsible for ensuring all emitted data complies with privacy standards.

## Getting started

Follow these steps to implement journey tracking in your app.

### Server events

You can send events solely on the backend and use the front‑end only to establish and pass along the journeyId. To do this, thread the active `journey ID` from your front‑end to your backend routes.

```
import { telemetry } from '@devvit/analytics/client/reddit';

export async function submitScore(score: number): Promise<void> {
const journeyId = telemetry.getActiveJourneyId();

const response = await fetch('/api/score', {
method: 'POST',
headers: {
'content-type': 'application/json',
...(journeyId ? { 'x-devvit-journey-id': journeyId } : {}),
},
body: JSON.stringify({ score }),
});

const data = (await response.json()) as { journeyId?: string };

if (data.journeyId) {
telemetry.setJourneyId(data.journeyId);
}
}
```

On the server, read the incoming `journeyId` and use it for correlation in your own route.

```
import express from 'express';
import { telemetry } from '@devvit/analytics/server/reddit';

const app = express();

app.use(express.json());

app.post('/api/score', async (req, res) => {
const journeyIdHeader = req.header('x-devvit-journey-id');
const journeyId = typeof journeyIdHeader === 'string' ? journeyIdHeader : '';

console.log('score event', {
journeyId,
score: req.body.score,
});

await telemetry.endJourney({
journeyId,
complete: true,
game: { win: true, score: req.body.score },
});

res.json({ ok: true });
});

```

### Client events

If you don’t want to manually send server-events, you can use the generic client side events. In this case, the `JourneyId` is handled. In this case, you won’t need to pass a `JourneyId` when calling progress and so forth. You also won’t need `telemetry.getActiveJourneyId()` unless you’re curious about that data.

Note: This also requires using the route adapters provided in `@devvit/analytics/server/reddit`

```
// client
import { telemetry } from '@devvit/analytics/client/reddit';

const activeJourneyId = telemetry.getActiveJourneyId();

await telemetry.progress({
progress: 0.5,
action: 'level_progress',
});

```

```
// server
import { createTelemetryRouter } from '@devvit/analytics/server/reddit';
app.use(createTelemetryRouter());

```
Loading
Loading