npx skills add ...
npx skills add getsentry/sentry-for-ai --skill sentry-tanstack-start-sdk
npx skills add getsentry/sentry-for-ai --skill sentry-tanstack-start-sdk
Full Sentry SDK setup for TanStack Start React. Use when asked to "add Sentry to TanStack Start", "install @sentry/tanstackstart-react", or configure error monitoring, tracing, session replay, logs, or user feedback in a TanStack Start React app.
The same skill content is published under more than one repo. The install counts are split across them; any of these commands works.
All Skills > SDK Setup > TanStack Start React SDK
Opinionated wizard that scans your TanStack Start React project and guides you through complete Sentry setup for browser and server runtimes.
@sentry/tanstackstart-reactsentryTanstackStart, wrapFetchWithSentry, instrument.server.mjs, or TanStack Start middleware instrumentationNote: This SDK is currently alpha and documented as compatible with TanStack Start
1.0 RC. Always verify against docs.sentry.io/platforms/javascript/guides/tanstackstart-react/ before implementing.
Run these commands to understand the project before making any recommendations:
What to determine:
| Question | Impact |
|---|---|
@tanstack/react-start present? | Confirms this skill is the right setup path |
@sentry/tanstackstart-react already installed? | Skip install and go to feature tuning |
src/router.tsx exists? | Client-side Sentry.init placement |
src/start.ts exists? | Global middleware setup for server-side errors |
src/server.ts exists? | Server entry instrumentation placement |
instrument.server.mjs exists? | Runtime startup instrumentation path |
vite.config.ts exists? | Add sentryTanstackStart plugin and source maps |
SENTRY_AUTH_TOKEN configured? | Source map upload readiness |
| Backend directory found? | Trigger Phase 4 cross-link suggestion |
Present a concrete recommendation based on what you found. Do not ask open-ended questions — lead with a proposal:
Recommended (core coverage):
Optional (enhanced observability):
Recommendation logic:
| Feature | Recommend when... |
|---|---|
| Error Monitoring | Always — non-negotiable baseline |
| Tracing | Usually yes for TanStack Start; route + fetch instrumentation gives immediate value |
| Session Replay | User-facing app, login flows, checkout flows, or hard-to-reproduce UX bugs |
| Logs | Existing logging strategy, support workflow, or trace/log correlation needs |
| User Feedback | Team wants direct user reports without leaving the app |
Propose: "I recommend Error Monitoring + Tracing + Session Replay. Want me to also enable Logs and User Feedback?"
src/router.tsxInitialize Sentry inside the router factory and gate it to the browser:
instrument.server.mjsCreate instrument.server.mjs in project root:
vite.config.tssentryTanstackStart should be the last plugin:
If the token is stored in .env, load it with loadEnv in the Vite config before passing it to the plugin.
src/server.tsWrap the fetch handler with wrapFetchWithSentry:
src/start.tsThese middleware capture server-side request and function errors:
Sentry middleware should be first in each array.
Choose one runtime method:
| Runtime pattern | Use when... | Notes |
|---|---|---|
--import flag | You can control Node startup flags | Preferred for production monitoring |
Direct import in src/server.ts | Host restricts startup flags (for example serverless hosts) | Limits instrumentation to native Node APIs |
--import examples:
Direct import fallback (top of src/server.ts):
Walk through features one at a time. Load the reference file, follow steps exactly, and verify before moving on:
| Feature | Reference | Load when... |
|---|---|---|
| Error Monitoring | ${SKILL_ROOT}/references/error-monitoring.md | Always |
| Tracing | ${SKILL_ROOT}/references/tracing.md | Route/API performance visibility needed |
| Session Replay | ${SKILL_ROOT}/references/session-replay.md | User-facing app |
| Logs | ${SKILL_ROOT}/references/logging.md | Structured logs and correlation needed |
| User Feedback | ${SKILL_ROOT}/references/user-feedback.md | In-app feedback collection needed |
| TanStack Start Features | ${SKILL_ROOT}/references/tanstackstart-features.md | Server entry, Vite plugin, source maps, runtime startup |
For each feature: Read ${SKILL_ROOT}/references/<feature>.md, follow steps exactly, verify it works.
Sentry.init() Options| Option | Type | Default | Notes |
|---|---|---|---|
dsn | string | — | Required; SDK is disabled when empty |
dataCollection | object | conservative unless set | Fine-grained control over auto-collected categories (userInfo, cookies, httpHeaders, httpBodies, queryParams, genAI). When omitted, the SDK falls back to sendDefaultPii (default false). Passing the object — even {} — flips unset categories to their permissive defaults; opt out per category. |
integrations | Integration[] | SDK defaults | Include TanStack Router tracing, replay, feedback as needed |
enableLogs | boolean | false | Enables Sentry.logger.* APIs |
tracesSampleRate | number | — | 1.0 in development, lower in production |
replaysSessionSampleRate | number | — | Fraction of all sessions recorded |
replaysOnErrorSampleRate | number | — | Fraction of error sessions recorded |
tunnel | string | — | Optional ad-blocker bypass endpoint |
debug | boolean | false | SDK diagnostic logging |
| API | Purpose |
|---|---|
tanstackRouterBrowserTracingIntegration(router) | Browser navigation tracing |
wrapFetchWithSentry(...) | Server request tracing + error capture on fetch handler |
sentryGlobalRequestMiddleware | Captures request-level server errors |
sentryGlobalFunctionMiddleware | Captures server function errors |
sentryTanstackStart({...}) | Vite plugin for source maps and middleware instrumentation |
Trigger test events to confirm Sentry receives data.
Confirm in Sentry:
enableLogs: trueAfter completing TanStack Start setup, check whether a companion backend exists without Sentry:
If a backend exists without Sentry configured, suggest the matching skill:
| Backend detected | Suggest skill |
|---|---|
Go (go.mod) | sentry-go-sdk |
Python (requirements.txt, pyproject.toml) | sentry-python-sdk |
Ruby (Gemfile) | sentry-ruby-sdk |
Java (pom.xml, build.gradle) | Use @sentry/java docs |
| Node.js backend services | sentry-node-sdk |
| Issue | Solution |
|---|---|
| Events not appearing | Set debug: true, verify DSN, and ensure client/server init files both run |
| No server traces | Confirm src/server.ts uses wrapFetchWithSentry and runtime loads instrument.server.mjs |
| Server errors missing from route handlers | Ensure sentryGlobalRequestMiddleware and sentryGlobalFunctionMiddleware are first in arrays |
| Source maps not resolving | Verify SENTRY_AUTH_TOKEN, org, and project in sentryTanstackStart config |
SENTRY_AUTH_TOKEN undefined in Vite config | Use loadEnv(mode, process.cwd(), "") or .env.sentry-build-plugin |
| Replay not recording | Ensure replayIntegration() is in integrations and sample rates are non-zero |
| Feedback widget not visible | Confirm feedbackIntegration() is configured and check CSS z-index conflicts |
| Logs missing in Sentry | Set enableLogs: true and use Sentry.logger.* APIs |
| Direct-import setup misses library spans | Prefer --import startup when possible; direct import supports native Node instrumentation only |
| SSR rendering exceptions not auto-captured | Capture manually with Sentry.captureException in error boundaries / fallback handlers |
npm install @sentry/tanstackstart-react --saveimport * as Sentry from "@sentry/tanstackstart-react";
import { createRouter } from "@tanstack/react-router";
export const getRouter = () => {
const router = createRouter();
if (!router.isServer) {
Sentry.init({
dsn: "___PUBLIC_DSN___",
dataCollection: {
// userInfo: false,
// httpBodies: [],
},
integrations: [
Sentry.tanstackRouterBrowserTracingIntegration(router),
Sentry.replayIntegration(),
Sentry.feedbackIntegration({
colorScheme: "system",
}),
],
enableLogs: true,
tracesSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
});
}
return router;
};import * as Sentry from "@sentry/tanstackstart-react";
Sentry.init({
dsn: "___PUBLIC_DSN___",
dataCollection: {
// To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:
// https://docs.sentry.io/platforms/javascript/guides/tanstackstart-react/configuration/options/#dataCollection
// userInfo: false,
// httpBodies: [],
},
enableLogs: true,
tracesSampleRate: 1.0,
});import { defineConfig } from "vite";
import { sentryTanstackStart } from "@sentry/tanstackstart-react/vite";
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
export default defineConfig({
plugins: [
tanstackStart(),
sentryTanstackStart({
org: "___ORG_SLUG___",
project: "___PROJECT_SLUG___",
authToken: process.env.SENTRY_AUTH_TOKEN,
}),
],
});import { wrapFetchWithSentry } from "@sentry/tanstackstart-react";
import handler, { createServerEntry } from "@tanstack/react-start/server-entry";
export default createServerEntry(
wrapFetchWithSentry({
fetch(request: Request) {
return handler.fetch(request);
},
}),
);import {
sentryGlobalFunctionMiddleware,
sentryGlobalRequestMiddleware,
} from "@sentry/tanstackstart-react";
import { createStart } from "@tanstack/react-start";
export const startInstance = createStart(() => {
return {
requestMiddleware: [sentryGlobalRequestMiddleware],
functionMiddleware: [sentryGlobalFunctionMiddleware],
};
});{
"scripts": {
"dev": "NODE_OPTIONS='--import ./instrument.server.mjs' vite dev --port 3000",
"build": "vite build && cp instrument.server.mjs .output/server",
"start": "node --import ./.output/server/instrument.server.mjs .output/server/index.mjs"
}
}import "../instrument.server.mjs";<button
type="button"
onClick={() => {
throw new Error("Sentry Test Error");
}}
>
Break the world
</button><button
type="button"
onClick={async () => {
await Sentry.startSpan({ name: "Example Frontend Span", op: "test" }, async () => {
const res = await fetch("/api/sentry-example");
if (!res.ok) {
throw new Error("Sentry Example Frontend Error");
}
});
}}
>
Break the world
</button>Sentry.logger.info("User example action completed");
Sentry.logger.warn("Slow operation detected", { operation: "data_fetch", duration: 3500 });
Sentry.logger.error("Validation failed", { field: "email", reason: "Invalid email" });ls ../backend ../server ../api ../go ../python 2>/dev/null
cat ../go.mod ../requirements.txt ../pyproject.toml ../Gemfile ../pom.xml 2>/dev/null | head -5