Skip to content

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

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

test(tanstackstart): Add TanStack Start on Cloudflare Workers test app#20649
JPeer264 wants to merge 4 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 :)

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.

Yes it works - but I'm not sure if it is a hack of mine of the correct way of doing it. In any way, I can add the docs for it

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.37 kB - -
@sentry/browser - with treeshaking flags 24.82 kB - -
@sentry/browser (incl. Tracing) 44.24 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 46.46 kB - -
@sentry/browser (incl. Tracing, Profiling) 49.22 kB - -
@sentry/browser (incl. Tracing, Replay) 83.86 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 73.31 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 88.55 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 101.19 kB - -
@sentry/browser (incl. Feedback) 43.53 kB - -
@sentry/browser (incl. sendFeedback) 31.19 kB - -
@sentry/browser (incl. FeedbackAsync) 36.27 kB - -
@sentry/browser (incl. Metrics) 27.65 kB - -
@sentry/browser (incl. Logs) 27.78 kB - -
@sentry/browser (incl. Metrics & Logs) 28.47 kB - -
@sentry/react 28.11 kB - -
@sentry/react (incl. Tracing) 46.49 kB - -
@sentry/vue 31.24 kB - -
@sentry/vue (incl. Tracing) 46.09 kB - -
@sentry/svelte 26.39 kB - -
CDN Bundle 28.95 kB - -
CDN Bundle (incl. Tracing) 46.97 kB - -
CDN Bundle (incl. Logs, Metrics) 30.36 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 48.09 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 69.68 kB - -
CDN Bundle (incl. Tracing, Replay) 84.37 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 85.42 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 90.16 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 91.26 kB - -
CDN Bundle - uncompressed 84.98 kB - -
CDN Bundle (incl. Tracing) - uncompressed 140.53 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 89.17 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 144 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 214 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 259.24 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 262.69 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 272.94 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 276.38 kB - -
@sentry/nextjs (client) 49.01 kB - -
@sentry/sveltekit (client) 44.72 kB - -
@sentry/node-core 60.56 kB +0.02% +8 B 🔺
@sentry/node 165.62 kB +0.01% +10 B 🔺
@sentry/node - without tracing 73.58 kB +0.02% +9 B 🔺
@sentry/aws-serverless 107.74 kB +0.01% +6 B 🔺
@sentry/cloudflare (withSentry) - minified 169.66 kB - -
@sentry/cloudflare (withSentry) 428.38 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?

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.

Pretty sure it won't work, as the sourcemaps would be different than the final wrangler build (there is 1 more build step after this one)

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.

Btw I didn't know that the Vite plugin is also adding auto instrumentation. I cross-checked that one as well and it doesn't work it seems

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.

yes it does for middlewares. good to know

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

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.

It would definitely work, but wrapFetchWithSentry would only add another span to it right? I don't think it would give any additional benefits. Or do you mean that we use wrapFetchWithSentry instead of withSentry from the Cloudflare SDK?

Copy link
Copy Markdown
Member

@nicohrubec nicohrubec May 11, 2026

Choose a reason for hiding this comment

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

Yes currently it would only add one more span so it's fine if we don't use it, but in the future we might move the exception capture into this API and potentially also route parametrization so we wouldn't have to update the docs if we find a way to add both right away (because I think we definitely need the `withSentry`?)


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)

Copy link
Copy Markdown
Member Author

@JPeer264 JPeer264 May 11, 2026

Choose a reason for hiding this comment

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

Great catch. I removed the test because it originally didn't work because of the missing middleware. After readding the middleware I forgot to readd the test.

@JPeer264 JPeer264 requested a review from nicohrubec May 11, 2026 13:27
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