TanStack Start on Cloudflare
Learn how to instrument your TanStack Start app on Cloudflare Workers and capture your first errors with Sentry.
This guide is for TanStack Start deployed to Cloudflare Workers using the @cloudflare/vite-plugin. For Node.js-based deployments, see our TanStack Start guide.
Choose the features you want to configure, and this guide will show you how:
Run the command for your preferred package manager to add the Sentry SDK to your application:
npm install @sentry/cloudflare --save
npm install @sentry/cloudflare --save
yarn add @sentry/cloudflare
pnpm add @sentry/cloudflare
When deploying TanStack Start to Cloudflare Workers, you need to wrap the server entry point with Sentry.withSentry from @sentry/cloudflare. TanStack Start allows you to create a custom server entry file for this purpose.
Create a src/server.ts file that wraps the TanStack Start handler with Sentry.
Use wrapFetchWithSentry from @sentry/tanstackstart-react to instrument TanStack Start server functions with tracing.
Due to type differences between TanStack Start and Cloudflare Workers, you'll need to add a // @ts-expect-error comment as shown in the example. This is expected and doesn't affect functionality.
src/server.tsimport * as Sentry from "@sentry/cloudflare";
import { wrapFetchWithSentry } from "@sentry/tanstackstart-react";
import handler from "@tanstack/react-start/server-entry";
export default Sentry.withSentry(
() => ({
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/cloudflare/configuration/options/#dataCollection
// userInfo: false,
// httpBodies: [],
},
// ___PRODUCT_OPTION_START___ logs
// Enable logs to be sent to Sentry
enableLogs: true,
// ___PRODUCT_OPTION_END___ logs
// ___PRODUCT_OPTION_START___ performance
// Set tracesSampleRate to 1.0 to capture 100% of spans for tracing.
tracesSampleRate: 1.0,
// ___PRODUCT_OPTION_END___ performance
}),
// @ts-expect-error - handler is not typed as a Cloudflare handler
wrapFetchWithSentry(handler),
);
import * as Sentry from "@sentry/cloudflare";
import { wrapFetchWithSentry } from "@sentry/tanstackstart-react";
import handler from "@tanstack/react-start/server-entry";
export default Sentry.withSentry(
() => ({
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/cloudflare/configuration/options/#dataCollection
// userInfo: false,
// httpBodies: [],
},
// ___PRODUCT_OPTION_START___ logs
// Enable logs to be sent to Sentry
enableLogs: true,
// ___PRODUCT_OPTION_END___ logs
// ___PRODUCT_OPTION_START___ performance
// Set tracesSampleRate to 1.0 to capture 100% of spans for tracing.
tracesSampleRate: 1.0,
// ___PRODUCT_OPTION_END___ performance
}),
// @ts-expect-error - handler is not typed as a Cloudflare handler
wrapFetchWithSentry(handler),
);
Update your wrangler.jsonc (or wrangler.toml) to use your custom server entry:
wrangler.jsonc {
"name": "my-tanstack-app",
"main": "src/server.ts",
// ... rest of config
}
{
"name": "my-tanstack-app",
+ "main": "src/server.ts",
// ... rest of config
}
Initialize Sentry in your src/router.tsx file for client-side error tracking:
src/router.tsx+import * 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: {
+ // 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: [],
+ },
+
+ integrations: [
+ // ___PRODUCT_OPTION_START___ performance
+ Sentry.tanstackRouterBrowserTracingIntegration(router),
+ // ___PRODUCT_OPTION_END___ performance
+ // ___PRODUCT_OPTION_START___ session-replay
+ Sentry.replayIntegration(),
+ // ___PRODUCT_OPTION_END___ session-replay
+ // ___PRODUCT_OPTION_START___ user-feedback
+ Sentry.feedbackIntegration({
+ // Additional SDK configuration goes in here, for example:
+ colorScheme: "system",
+ }),
+ // ___PRODUCT_OPTION_END___ user-feedback
+ ],
+ // ___PRODUCT_OPTION_START___ logs
+
+ // Enable logs to be sent to Sentry
+ enableLogs: true,
+ // ___PRODUCT_OPTION_END___ logs
+ // ___PRODUCT_OPTION_START___ performance
+
+ // Set tracesSampleRate to 1.0 to capture 100% of spans for tracing.
+ tracesSampleRate: 1.0,
+ // ___PRODUCT_OPTION_END___ performance
+ // ___PRODUCT_OPTION_START___ session-replay
+
+ // Capture Replay for 10% of all sessions,
+ // plus for 100% of sessions with an error.
+ replaysSessionSampleRate: 0.1,
+ replaysOnErrorSampleRate: 1.0,
+ // ___PRODUCT_OPTION_END___ session-replay
+ });
+ }
return router;
}
+import * 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: {
+ // 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: [],
+ },
+
+ integrations: [
+ // ___PRODUCT_OPTION_START___ performance
+ Sentry.tanstackRouterBrowserTracingIntegration(router),
+ // ___PRODUCT_OPTION_END___ performance
+ // ___PRODUCT_OPTION_START___ session-replay
+ Sentry.replayIntegration(),
+ // ___PRODUCT_OPTION_END___ session-replay
+ // ___PRODUCT_OPTION_START___ user-feedback
+ Sentry.feedbackIntegration({
+ // Additional SDK configuration goes in here, for example:
+ colorScheme: "system",
+ }),
+ // ___PRODUCT_OPTION_END___ user-feedback
+ ],
+ // ___PRODUCT_OPTION_START___ logs
+
+ // Enable logs to be sent to Sentry
+ enableLogs: true,
+ // ___PRODUCT_OPTION_END___ logs
+ // ___PRODUCT_OPTION_START___ performance
+
+ // Set tracesSampleRate to 1.0 to capture 100% of spans for tracing.
+ tracesSampleRate: 1.0,
+ // ___PRODUCT_OPTION_END___ performance
+ // ___PRODUCT_OPTION_START___ session-replay
+
+ // Capture Replay for 10% of all sessions,
+ // plus for 100% of sessions with an error.
+ replaysSessionSampleRate: 0.1,
+ replaysOnErrorSampleRate: 1.0,
+ // ___PRODUCT_OPTION_END___ session-replay
+ });
+ }
return router;
}
To capture server-side errors from HTTP requests and server function calls, add Sentry's global middlewares to createStart() in your src/start.ts file.
The Sentry middleware should be the first middleware in the arrays to ensure all errors are captured.
SSR rendering exceptions are not captured by the middleware. Use captureException to manually capture those errors.
src/start.tsimport {
sentryGlobalFunctionMiddleware,
sentryGlobalRequestMiddleware,
} from "@sentry/tanstackstart-react";
import { createStart } from "@tanstack/react-start";
export const startInstance = createStart(() => {
return {
requestMiddleware: [sentryGlobalRequestMiddleware],
functionMiddleware: [sentryGlobalFunctionMiddleware],
};
});
import {
sentryGlobalFunctionMiddleware,
sentryGlobalRequestMiddleware,
} from "@sentry/tanstackstart-react";
import { createStart } from "@tanstack/react-start";
export const startInstance = createStart(() => {
return {
requestMiddleware: [sentryGlobalRequestMiddleware],
functionMiddleware: [sentryGlobalFunctionMiddleware],
};
});
To verify Sentry is capturing errors, add a test button to one of your pages:
<button
type="button"
onClick={() => {
throw new Error("Sentry Test Error");
}}
>
Break the world
</button>;
<button
type="button"
onClick={() => {
throw new Error("Sentry Test Error");
}}
>
Break the world
</button>;
Run your app with wrangler dev (or through your Vite build with Cloudflare plugin), click the button, and check your Sentry project for the error.
At this point, you should have integrated Sentry and should already be sending data to your Sentry project.
Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are:
- Learn how to manually capture errors
- Continue to customize your configuration
- Make use of Cloudflare-specific features
- Get familiar with Sentry's product features like tracing, insights, and alerts
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").