|
| 1 | +# Product usage analytics |
| 2 | + |
| 3 | +Posecode keeps Vercel pageviews and product-usage events separate. Pageviews |
| 4 | +answer “which routes were visited?”; the events below answer “did someone use |
| 5 | +the product?” |
| 6 | + |
| 7 | +## Provider and production configuration |
| 8 | + |
| 9 | +The implementation is provider-neutral at the call sites. Event names, payload |
| 10 | +types, failure isolation, and session deduplication live in |
| 11 | +`playground/src/analytics.ts`. The current adapter is |
| 12 | +`playground/src/vercel-analytics.ts`. |
| 13 | + |
| 14 | +Vercel Web Analytics pageviews remain enabled without extra configuration. |
| 15 | +Vercel's current plan table says custom events are **not available on Hobby**; |
| 16 | +they are available on Pro and Enterprise. Pro allows at most two properties per |
| 17 | +custom event. The schema below deliberately stays within that limit. |
| 18 | + |
| 19 | +To enable product events on a Vercel Pro or Enterprise production project: |
| 20 | + |
| 21 | +1. Enable Web Analytics for the project in Vercel. |
| 22 | +2. Set `VITE_PRODUCT_ANALYTICS_PROVIDER=vercel` for the Production environment. |
| 23 | +3. Redeploy so Vite includes the provider choice in the client bundle. |
| 24 | +4. Exercise one event and confirm it in **Project → Analytics → Events**. |
| 25 | + |
| 26 | +Do not set the variable on Hobby expecting dashboard data: Hobby continues to |
| 27 | +show pageviews but does not expose custom events. No alternate paid analytics |
| 28 | +vendor is installed. A future adapter can call `configureUsageAnalytics` |
| 29 | +without changing UI event call sites. |
| 30 | + |
| 31 | +Sources: |
| 32 | + |
| 33 | +- [Vercel custom events](https://vercel.com/docs/analytics/custom-events) |
| 34 | +- [Vercel Web Analytics limits and pricing](https://vercel.com/docs/analytics/limits-and-pricing) |
| 35 | + |
| 36 | +## Event dictionary |
| 37 | + |
| 38 | +| Event | Fires when | Properties | |
| 39 | +|---|---|---| |
| 40 | +| `preset_opened` | A bundled movement is actually opened at initial load or selected in the library. | `source`: `library`, `direct_url`, `shared_link`, or `landing_cta`; `preset_id`: bundled stable ID | |
| 41 | +| `editor_changed` | The first real CodeMirror user edit in the page session. Programmatic preset loads do not count. | `document_kind`: `preset`, `shared`, or `custom` | |
| 42 | +| `render_succeeded` | `viewer.load()` successfully accepts a new meaningful document revision. Lazy boot and repeated recompiles of the same revision are deduplicated. The animation frame loop never emits this event. | `trigger`: `initial`, `preset_open`, `shared_link`, or `editor_change`; `document_kind` | |
| 43 | +| `share_created` | The generated preset/encoded URL has successfully been written to the clipboard. | `share_kind`: `preset` or `encoded` | |
| 44 | +| `embed_docs_clicked` | The embed documentation CTA on `/for-products` is clicked. | `location`: `for_products` | |
| 45 | +| `install_command_copied` | An npm/npx command on `/for-products` is successfully written to the clipboard. | `command`: `embed`, `packages`, or `mcp`; `location`: `for_products` | |
| 46 | + |
| 47 | +## Reading the dashboard |
| 48 | + |
| 49 | +Open **Analytics → Events**, select an event, then drill into its properties. |
| 50 | +Useful readings include: |
| 51 | + |
| 52 | +- `preset_opened` grouped by `source` separates library discovery from direct, |
| 53 | + shared, and landing-page entry. |
| 54 | +- Compare `editor_changed` and `render_succeeded` counts to see whether editing |
| 55 | + reaches a valid renderer update. They are intentionally not a strict funnel: |
| 56 | + initial and preset renders also count. |
| 57 | +- `share_created` is a confirmed clipboard outcome, not a button-click count. |
| 58 | +- Group `install_command_copied` by `command` to compare integration intent. |
| 59 | + |
| 60 | +Vercel reports aggregate events rather than a user-level funnel. Do not attempt |
| 61 | +to join individual visitors or reconstruct sessions from these payloads. |
| 62 | + |
| 63 | +## Privacy and resilience |
| 64 | + |
| 65 | +Events never contain Posecode source text, authoring prompts, personal data, |
| 66 | +full share tokens, query strings, referrers, or sensitive URLs. `preset_id` is a |
| 67 | +bounded public catalogue identifier; all other values are closed enums. |
| 68 | + |
| 69 | +Every analytics call is best-effort and catches provider failures. Ad blockers, |
| 70 | +network failures, a missing provider configuration, or plan limitations do not |
| 71 | +change editing, rendering, sharing, navigation, or clipboard behavior. |
0 commit comments