Skip to content
supastack
Browse documentation
WebNext.js

For AI agents: fetch the complete documentation index at /llms.txt, the full documentation corpus at /llms-full.txt, the agent skill at /skill.md, or this page as Markdown at /docs/web/setup-observability.md (or send Accept: text/markdown).

Set up observability

Error tracking, product analytics, and failure alerts — all optional.

Find useful information when an action fails

Observability means seeing what your app did. Begin with the terminal running your Web server: repeat one failing action and read the first error and any correlation ID, a label linking messages from the same request. Share the command, time and sanitized error when asking for help; do not share .env files or tokens.

For hosted error reports, follow Health and operations to configure the supported monitoring settings in apps/web/.env.local or the host's environment dashboard. Save and restart the server. Trigger a controlled test failure in a test environment and confirm it appears with the correct workspace context. Monitoring being configured does not prove it received an event.

ALERT_WEBHOOK_URL is an optional HTTPS destination for job and terminal webhook-delivery failure alerts. If you need it, create a compatible incoming endpoint and save its URL server-side; otherwise leave it empty. Ask an agent to simulate one failure and confirm exactly one alert, with no secrets in its text. Do not trigger paid work or failures in customer accounts for this test.

Keep a workspace audit trail

Audit records capture changes such as provider configuration updates within a workspace. Resolve the authenticated workspace before reading or writing these records, and preserve that scope when adding product-specific events.

Record the action and identifiers needed to understand it. Provider credentials and other sensitive values must stay out of audit payloads and logs.

Capture product events

The observability package exposes an AnalyticsClient adapter and workspace-scoped AnalyticsEvent values. Each event carries a name, distinct identity, workspaceId, and optional properties.

Use createObservability to route events through your configured analytics client. Structured properties are redacted before delivery; keep sensitive free-form text out of event names and property values as well.

Report errors with safe context

ErrorClient captures exceptions with workspaceId tags and structured extra context. The shared observability layer sanitizes exceptions and redacts sensitive context before forwarding them to the configured client.

Use local adapters to verify captured events and exceptions without calling a monitoring provider. Test that workspace tags remain present and credentials are removed before enabling an external destination.

Follow a request across tasks, jobs and webhooks

Entry boundaries mint a corr_<uuid> correlation id that links the originating request to the work it triggers. AI-task submission stamps the id on the task payload and the ai_task_submitted event, every billing webhook receiver mints one per request, and the scheduler mints one per dispatched job.

The same id rides job.completed and ai_task_completed event properties, captureException extras, the webhook_event ledger payload and each webhook_delivery payload meta — so it lands inside the signed body a subscriber receives. Missing or malformed ids are tolerated: the consumer mints a fresh id instead of rejecting older rows.

Alert on real failures

Set ALERT_WEBHOOK_URL to any HTTPS endpoint that accepts a JSON POST shaped {text, name, severity, context}; a Slack-style incoming webhook works as-is. Alerts are fire-and-forget with a five-second timeout, a failed delivery logs one console warning, and the alerter noops while the variable is unset.

The shipped alerts are job.failed (warning — a job handler threw or a job type is unknown) and webhook.delivery_failed (critical — only when an outgoing delivery reaches terminal failure after its final attempt; ordinary retries stay quiet and each delivery row alerts at most once).

Measure durations and stream structured logs

serverObservability.measure times an async operation and emits a <name>.duration analytics event carrying durationMs — on success and on failure, without masking the original error. The ai.task.execute job run is already wrapped, so task execution duration lands in the configured analytics client.

serverObservability.logger writes one JSON line per record to stdout with environment and service base fields; the shared redaction layer strips secrets before any line is emitted.

Setup and configuration

1. Set SENTRY_DSN for error reporting — exceptions are captured with correlation IDs and workspace tags.

2. Set NEXT_PUBLIC_POSTHOG_KEY and NEXT_PUBLIC_POSTHOG_HOST for product analytics — these are public browser values by design.

3. Set ALERT_WEBHOOK_URL to a Slack-compatible endpoint for failure alerts — the app POSTs {text, name, severity, context} JSON.

SENTRY_DSN=https://…@….ingest.sentry.io/…

NEXT_PUBLIC_POSTHOG_KEY=phc_…
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com

ANALYTICS_PROVIDER=off    # off | local | plausible | posthog
# ANALYTICS_SITE_ID=
# ANALYTICS_HOST=

ALERT_WEBHOOK_URL=https://hooks.slack.com/services/…

Implementation workflow

The observability layer sanitizes exceptions and redacts known secret keys before forwarding — but free-form event text is the author's responsibility, so keep credentials out of event names and property values.

Local adapters let tests assert on captured events and exceptions without calling Sentry or PostHog; none of these variables are required to run locally.

Signals flowing? Continue to Set up custom domains.

Verification and troubleshooting

Trigger a test exception and confirm it lands in Sentry with secrets stripped from the payload, then check that a wired failure POSTs to ALERT_WEBHOOK_URL. If events never arrive, verify the DSN/key pair and that the host is reachable from the server.

If you want to continue setup, read Set up custom domains.

Frequently asked questions

14 questions

What is supastack?

supastack is a modular foundation for building AI-powered SaaS products. It brings together common infrastructure so you can focus on product-specific features.

Does it support web and mobile?

Yes. supastack includes Next.js and Expo apps as starting points for web and mobile experiences.

What authentication is included?

Better Auth covers email OTP, magic-link, and social sign-in; email/password stays available at the API layer and through the Auth.js credentials engine for products that need it. Personal workspaces are provisioned with the account so product records stay scoped from day one.

How does it support AI?

supastack includes configurable multi-provider AI, usage tracking, budgets, and encrypted bring-your-own-key support.

How are subscriptions handled?

For products built on the kit, Stripe billing, subscriptions, and entitlements form the paid-access foundation. Provider secrets stay server-only.

Where does my product-specific code live?

Product-specific features remain in a separate codebase while the product configures and integrates supastack’s foundation modules.

How does supastack pricing work?

The kit is a one-time purchase with lifetime updates: One Platform at $249 (temporary launch price, $100 off the regular $349) — your pick of Next.js (Web), Expo (iOS & Android), or Tauri (macOS & Windows Desktop) — or the All Platforms Bundle at $499 (temporary launch price, $100 off the regular $599) with every platform and the full monorepo, plus $75 per extra developer seat. No kit subscription. Checkout on this site delivers your license key by email, with repository access via GitHub invite.

How do workspaces scope my data?

User-owned records are scoped by workspaceId. Identity, entitlements, AI usage, billing events, and audit entries stay inside the personal workspace boundary.

How do background jobs work?

Trigger.dev is the explicit job runtime. The JobRunner contract only promises enqueue, status, and cancel—workflow semantics stay Trigger.dev-specific and explicit.

How is email different from outreach?

Transactional email covers product workflows such as completion notices. Cold outreach and campaigns are product concerns outside this kit’s email module.

How do mobile purchases work?

Mobile includes native purchases and restore through RevenueCat, with access verified by your server. Configure the store accounts and complete device testing before release. Web billing remains separate.

Where do AI provider keys live?

Bring-your-own-key credentials are encrypted and stay server-only. Keys are redacted from logs; usage and budgets remain visible at the workspace level.

Which payment methods does checkout accept?

The Stripe-hosted checkout accepts cards and can also offer Alipay and WeChat Pay once those wallets are enabled on the Stripe account — handy for buyers in China. Wallet authorizations confirm asynchronously, so the license page updates as soon as the payment clears.

Can I get a refund?

After you've got access to the repository, supastack is yours forever, so it cannot be refunded. But rest assured, you get the complete source code with lifetime updates to build and ship unlimited products for yourself or clients. You just cannot resell the code or redistribute the repository as a starter kit or template.

EN
Theme