Skip to content

test(tanstackstart): Add TanStack Start on Cloudflare Workers test app#20649

Open
JPeer264 wants to merge 2 commits intodevelopfrom
jp/tanstack-start-cloudflare
Open

test(tanstackstart): Add TanStack Start on Cloudflare Workers test app#20649
JPeer264 wants to merge 2 commits intodevelopfrom
jp/tanstack-start-cloudflare

Conversation

@JPeer264
Copy link
Copy Markdown
Member

@JPeer264 JPeer264 commented May 4, 2026

Adds an e2e test application for TanStack Start deployed to Cloudflare Workers using @sentry/cloudflare. The setup uses a custom server entry point that wraps the TanStack Start handler with Sentry.withSentry.

Unfortunately the type safety is not great yet with Sentry.withSentry and TanStack Start, so this needs to be adapted in another PR (or in v11 if it is not yet possible).

Closes #18669

@JPeer264 JPeer264 requested a review from nicohrubec May 4, 2026 12:44
@JPeer264 JPeer264 self-assigned this May 4, 2026
@JPeer264 JPeer264 force-pushed the jp/tanstack-start-cloudflare branch from e581ac8 to 8dd6f21 Compare May 4, 2026 12:44
export const Route = createRootRoute({
head: () => {
const traceData = getTraceData();
const sentryMeta = Object.entries(traceData).map(([key, value]) => ({
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is the best way in TanStack to add trace propagation, couldn't find anything specific in the docs

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have never looked into this, does that work? If yes that's amazing then we can document how to set that up :)

tracesSampleRate: 1.0,
environment: 'qa',
}),
// @ts-expect-error - handler is not typed as a Cloudflare handler
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the type error

expect(errorEvent.contexts?.trace?.span_id).toEqual(expect.any(String));
});

// Note: API route errors in TanStack Start are handled internally by the framework
Copy link
Copy Markdown
Member Author

@JPeer264 JPeer264 May 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a note there. I think the TanStack Start middleware won't work in Cloudflare (yet?), as the middleware is somehow added with the tanstack start SDK?!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that works now 😎

"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "wrangler dev --var E2E_TEST_DSN:$E2E_TEST_DSN --log-level=$(test $CI && echo 'none' || echo 'log')",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing quotes around --var value in preview script

Medium Severity

The preview script passes --var E2E_TEST_DSN:$E2E_TEST_DSN without quotes around the value. Every other Cloudflare test app in the repo (cloudflare-workers, cloudflare-local-workers, cloudflare-mcp, cloudflare-workersentrypoint, astro-6-cf-workers) uses the quoted form --var \"E2E_TEST_DSN:$E2E_TEST_DSN\". Since DSN values contain shell-sensitive characters like :// and @, the unquoted expansion could cause parsing issues depending on the shell environment in CI.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 8dd6f21. Configure here.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

size-limit report 📦

Path Size % Change Change
@sentry/browser 26.3 kB - -
@sentry/browser - with treeshaking flags 24.78 kB - -
@sentry/browser (incl. Tracing) 44.17 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 46.39 kB - -
@sentry/browser (incl. Tracing, Profiling) 49.14 kB - -
@sentry/browser (incl. Tracing, Replay) 83.55 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 73.01 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 88.23 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 100.84 kB - -
@sentry/browser (incl. Feedback) 43.44 kB - -
@sentry/browser (incl. sendFeedback) 31.11 kB - -
@sentry/browser (incl. FeedbackAsync) 36.19 kB - -
@sentry/browser (incl. Metrics) 27.6 kB - -
@sentry/browser (incl. Logs) 27.73 kB - -
@sentry/browser (incl. Metrics & Logs) 28.43 kB - -
@sentry/react 28.04 kB - -
@sentry/react (incl. Tracing) 46.4 kB - -
@sentry/vue 31.18 kB - -
@sentry/vue (incl. Tracing) 46.02 kB - -
@sentry/svelte 26.32 kB - -
CDN Bundle 28.91 kB - -
CDN Bundle (incl. Tracing) 46.94 kB - -
CDN Bundle (incl. Logs, Metrics) 30.34 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 48.04 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 69.4 kB - -
CDN Bundle (incl. Tracing, Replay) 84.07 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 85.15 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 89.89 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 90.97 kB - -
CDN Bundle - uncompressed 84.88 kB - -
CDN Bundle (incl. Tracing) - uncompressed 140.44 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 89.08 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 143.9 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 212.99 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 258.24 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 261.69 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 271.94 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 275.38 kB - -
@sentry/nextjs (client) 48.9 kB - -
@sentry/sveltekit (client) 44.64 kB - -
@sentry/node-core 59.81 kB +0.02% +9 B 🔺
@sentry/node 163.43 kB +0.01% +7 B 🔺
@sentry/node - without tracing 72.28 kB +0.02% +9 B 🔺
@sentry/aws-serverless 106.95 kB +0.01% +7 B 🔺
@sentry/cloudflare (withSentry) - minified 166.9 kB - -
@sentry/cloudflare (withSentry) 421.79 kB - -

View base workflow run

"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "wrangler dev --var E2E_TEST_DSN:$E2E_TEST_DSN --log-level=$(test $CI && echo 'none' || echo 'log')",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preview bypasses built app

Medium Severity

The preview script starts wrangler dev, but this app is built through @cloudflare/vite-plugin. wrangler dev bypasses the Vite preview output that pnpm build creates, so Playwright can run a source Worker without the generated TanStack assets instead of the Cloudflare build under test.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d4d6179. Configure here.

@JPeer264 JPeer264 force-pushed the jp/tanstack-start-cloudflare branch from d4d6179 to 2d2ea64 Compare May 5, 2026 16:20
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 3 total unresolved issues (including 2 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2d2ea64. Configure here.


const clientTransactionPromise = waitForTransaction('tanstackstart-react-cloudflare', transactionEvent => {
return transactionEvent?.contexts?.trace?.op === 'pageload' && transactionEvent?.transaction === '/';
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Telemetry wait can flake

Low Severity

This hits the project rule about flaky telemetry waits: the GET / transaction predicate can match delayed root transactions from earlier tests. If serverTransactionPromise resolves with an older request, the trace comparison uses unrelated server and client events and flakes.

Fix in Cursor Fix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 2d2ea64. Configure here.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't hurt using a longer route I guess

export const Route = createRootRoute({
head: () => {
const traceData = getTraceData();
const sentryMeta = Object.entries(traceData).map(([key, value]) => ({
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have never looked into this, does that work? If yes that's amazing then we can document how to set that up :)

server: {
port: 3030,
},
plugins: [cloudflare({ viteEnvironment: { name: 'ssr' } }), tsConfigPaths(), tanstackStart(), viteReact()],
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

q: have you tried using the sentry vite plugin here?

environment: 'qa',
}),
// @ts-expect-error - handler is not typed as a Cloudflare handler
handler,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

q: wondering if we could wrap this handler with wrapFetchWithSentry somehow? right now it's not that important but would future-proof us if that works


const clientTransactionPromise = waitForTransaction('tanstackstart-react-cloudflare', transactionEvent => {
return transactionEvent?.contexts?.trace?.op === 'pageload' && transactionEvent?.transaction === '/';
});
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't hurt using a longer route I guess


export const Route = createFileRoute('/ssr-error')({
loader: () => {
throw new Error('Sentry SSR Test Error');
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l: this as well as the flush endpoint are not used I think? in other Tanstack Start apps we have a test that asserts that ssr errors are not captured (where this is used). fine to leave this out for this one I think but then we could trim down the application a bit (i.e. remove the flush endpoint and ssr error)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Investigate cloudflare support

2 participants