diff --git a/content/docs/products/prism/concepts.mdx b/content/docs/products/prism/concepts.mdx new file mode 100644 index 0000000..c64ba2f --- /dev/null +++ b/content/docs/products/prism/concepts.mdx @@ -0,0 +1,29 @@ +--- +title: Concepts +description: How Prism counts, stores, and serves analytics +--- + +## Cookieless by design + +Prism never sets a cookie and never stores a raw IP address or a persistent identifier. A visitor is counted with a salted hash that rotates daily, so the same person on the same day is one visitor, and the link back to any individual disappears when the salt rotates. There is nothing to consent to and no cross-site profile to build. + +## Events + +Two kinds of events flow into the collector: + +- **Pageviews**, reported automatically on route change. +- **Custom events**, named signals you send yourself (a sign-up, a purchase, a feature used), each carrying a small set of properties. + +Events are batched in the client and flushed with `navigator.sendBeacon`, so a navigation away from the page never drops the events queued on it. + +## The collector + +Instrumented apps report to a public HTTP collector at `POST https://api.prism.omni.dev/collect`. The collector validates and stores raw events; it accepts writes only and never reads back. + +## Daily rollups + +A rollup worker materializes raw events into per-product daily aggregates. Reads hit these rollups rather than the raw event stream, which keeps the dashboard fast as volume grows. Rollups are retained for the window your [tier](/products/prism/pricing) allows. + +## Reads are gated + +Writes are public (any instrumented app can report), but reads are not. The dashboard and the read-only GraphQL API both sit behind an Omni sign-in, scoped to your workspace. The API exposes queries only: mutations are denied at the schema level. diff --git a/content/docs/products/prism/dashboard.mdx b/content/docs/products/prism/dashboard.mdx new file mode 100644 index 0000000..ced2d86 --- /dev/null +++ b/content/docs/products/prism/dashboard.mdx @@ -0,0 +1,24 @@ +--- +title: Dashboard +description: Read per-product rollups at prism.omni.dev +--- + +The dashboard at [prism.omni.dev](https://prism.omni.dev) reads per-product daily rollups for your workspace. It is gated behind an Omni sign-in. + +## What it shows + +- **Visitors and pageviews** over the selected range, with the change against the previous period. +- **Top pages**, ranked by traffic. +- **Custom events**, the named signals you report from your app. + +## Range control + +Pick the window you want to see. The dashboard compares it against the preceding window of the same length and surfaces the delta, so you read trends rather than raw totals. + +## Try it first + +The [public demo](https://prism.omni.dev/demo) runs the real dashboard on sample data, with no sign-in, so you can see the shape of the product before instrumenting anything. + +## GraphQL read API + +Prefer to pull the numbers yourself? Prism exposes a read-only GraphQL API behind the same Omni sign-in. It serves queries only; mutations are denied at the schema level. The read API is available on the [Pro and Team tiers](/products/prism/pricing). diff --git a/content/docs/products/prism/getting-started.mdx b/content/docs/products/prism/getting-started.mdx new file mode 100644 index 0000000..65716fe --- /dev/null +++ b/content/docs/products/prism/getting-started.mdx @@ -0,0 +1,15 @@ +--- +title: Getting Started +description: Point a product at the collector and watch events roll up +--- + +1. **Sign In** + Prism dashboards are gated behind an Omni sign-in. Sign in at [prism.omni.dev](https://prism.omni.dev) to reach your workspace. Prefer a look before you commit? The [public demo](https://prism.omni.dev/demo) runs on sample data. +2. **Instrument a Product** + Point an app at the collector with a single environment variable and report pageviews through the shared analytics client. See [Instrumenting a Product](/products/prism/instrumenting) for the three-step setup. +3. **Send Events** + Pageviews report automatically on route change. Track anything else with a named call, for example `prism.track("app_opened", { appId })`. +4. **Read the Dashboard** + Open the [dashboard](/products/prism/dashboard) to see per-product daily rollups: visitors, pageviews, top pages, and deltas over a range you control. +5. **Upgrade as You Grow** + The free tier is hard-capped for hobby use. When you need more events, retention, or products, move to a paid [tier](/products/prism/pricing). diff --git a/content/docs/products/prism/index.mdx b/content/docs/products/prism/index.mdx new file mode 100644 index 0000000..b97a833 --- /dev/null +++ b/content/docs/products/prism/index.mdx @@ -0,0 +1,72 @@ +--- +title: 📊 Prism +description: Privacy-first product analytics +--- + +import { ProductOverview, RunPaths } from "@/components/docs"; +import app from "@/lib/config/app.config"; +import { + PiChartLineUpBold, + PiShieldCheckBold, + PiLightningBold, +} from "react-icons/pi"; + +, + className: + "bg-violet-100 text-violet-800 dark:bg-violet-900/20 dark:text-violet-300", + }, + { + label: "Privacy-First", + icon: , + className: + "bg-violet-100 text-violet-800 dark:bg-violet-900/20 dark:text-violet-300", + }, + { + label: "Postgres-Native", + icon: , + className: + "bg-violet-100 text-violet-800 dark:bg-violet-900/20 dark:text-violet-300", + }, + ]} + links={[ + { + href: "https://prism.omni.dev", + label: "Visit App", + type: "website", + className: + "bg-violet-100 text-violet-800 dark:bg-violet-900/20 dark:text-violet-300", + }, + { + href: `${app.socials.github}/prism-stack`, + label: "Visit Repository", + type: "repository", + }, + ]} + alerts={[ + { + title: "🚧 Under Construction", + description: + "Prism is new! Expect this documentation to change rapidly and have rough edges.", + }, + { + title: "💡 Big Idea", + description: + "Understand how people use your product without tracking them: cookieless by design, with the raw data in your own Postgres.", + }, + ]} +/> + +**Omni Prism** is first-party, privacy-first product analytics. It ingests pageviews and custom events over a public, cookieless HTTP collector and materializes them into fast daily rollups you read from a dashboard or a GraphQL API. + +Prism counts visitors with a daily-rotating salted hash, never a raw IP or a persistent cookie, so there is nothing to consent to and no cross-site profile to build. Every product in your workspace reports through the shared analytics client in [`@omnidotdev/providers`](https://github.com/omnidotdev/providers), so there is no Prism-specific SDK to install. + +## Self-Hosting + +Run Prism on your own machine with one command, or spin up the source with live +reload to contribute. + + diff --git a/content/docs/products/prism/instrumenting.mdx b/content/docs/products/prism/instrumenting.mdx new file mode 100644 index 0000000..cca2702 --- /dev/null +++ b/content/docs/products/prism/instrumenting.mdx @@ -0,0 +1,42 @@ +--- +title: Instrumenting a Product +description: Report pageviews and events through the shared analytics client +--- + +Prism ingests events over a public, cookieless HTTP collector. Any Omni app reports through the analytics client in [`@omnidotdev/providers`](https://github.com/omnidotdev/providers), so there is no Prism-specific SDK to install. + +## 1. Point the app at the collector + +Set the collector URL in the app's deploy environment: + +```bash +VITE_PRISM_COLLECTOR_URL=https://api.prism.omni.dev +``` + +When unset, analytics degrades to a no-op, so local and preview builds never emit. + +## 2. Create a client and auto-report pageviews + +Create a client once and report pageviews on every route change: + +```ts +import { createPrismClient, usePageview } from "@omnidotdev/providers/analytics"; + +const prism = createPrismClient({ + collectorUrl: PRISM_COLLECTOR_URL, + product: "", +}); + +// in your root component +usePageview(prism, pathname); +``` + +## 3. Track custom events + +Report any named event from anywhere in the app: + +```ts +prism.track("app_opened", { appId }); +``` + +Events are cookieless, batched in the client, and flushed with `navigator.sendBeacon` so a navigation never drops them. Once events arrive, read them from the [dashboard](/products/prism/dashboard). diff --git a/content/docs/products/prism/meta.json b/content/docs/products/prism/meta.json new file mode 100644 index 0000000..601a313 --- /dev/null +++ b/content/docs/products/prism/meta.json @@ -0,0 +1,10 @@ +{ + "title": "📊 Prism", + "pages": [ + "getting-started", + "concepts", + "instrumenting", + "dashboard", + "pricing" + ] +} diff --git a/content/docs/products/prism/pricing.mdx b/content/docs/products/prism/pricing.mdx new file mode 100644 index 0000000..598a8f2 --- /dev/null +++ b/content/docs/products/prism/pricing.mdx @@ -0,0 +1,43 @@ +--- +title: Pricing +description: Prism tiers, from free hobby use to team scale +--- + +Prism is priced by monthly event volume. The free tier is hard-capped for hobby use; paid tiers raise the event allowance, retention window, and number of products you can track. Live pricing is always shown at [prism.omni.dev/pricing](https://prism.omni.dev/pricing). + +## Free + +Start measuring, no cost. + +- 10,000 events/month +- 1 product +- 30-day data retention +- Cookieless, privacy-first by default +- Pageviews and custom events + +## Pro + +For growing products. **$9/month** (or $90/year). + +- Everything in Free +- 500,000 events/month +- Up to 10 products +- 1-year data retention +- GraphQL read API +- Up to 5 members + +## Team + +For teams and scale. **$29/month** (or $290/year). + +- Everything in Pro +- 5,000,000 events/month +- Unlimited products +- Unlimited data retention +- GraphQL read API +- Unlimited members +- Priority support + +## Self-hosting + +Prism is Apache-2.0 and self-hostable. Run the full stack yourself with Docker Compose and the tiers above do not apply: see the [overview](/products/prism) for the self-hosting paths.