Repository navigation
@sentry/astro: Use the Cloudflare Vite plugin for Workers builds #25344
Copy link
Copy link
Closed
Labels
javascriptPull requests that update javascript codePull requests that update javascript code
Description
On Cloudflare Workers, an Astro app still needs a hand-written sentry.server.config.js that is also the wrangler main:
// sentry.server.config.js
import * as Sentry from '@sentry/cloudflare';
import handler from '@astrojs/cloudflare/entrypoints/server';
export default Sentry.withSentry(env => ({ dsn: env.E2E_TEST_DSN /* ... */ }), handler);// wrangler.jsonc
{ "main": "./sentry.server.config.js" }The goal is the setup that @sentry/cloudflare/vite gives other frameworks: wrangler main stays the package entry, and the options live in an instrument.server.* file beside the wrangler config.
// wrangler.jsonc
{ "main": "@astrojs/cloudflare/entrypoints/server" }// instrument.server.js
import { defineCloudflareOptions } from '@sentry/cloudflare';
export default defineCloudflareOptions(env => ({ dsn: env.E2E_TEST_DSN /* ... */ }));@sentry/cloudflare/vite will be able to wrap a package-specifier main as of #24522. The rest of the work is in @sentry/astro.
What blocks it
I tried this setup in the astro-6-cf-workers e2e app, with sentryCloudflareVitePlugin() added to vite.plugins in astro.config.mjs. The Cloudflare plugin wrapped the entry, but 9 of 11 tests failed with Sentry Logger [error]: Transport disabled.
- Default server init with no DSN. With no
sentry.server.config.*file, the integration falls back tobuildServerSnippet()(packages/astro/src/integration/snippets.ts). It injectsSentry.init({ dsn: import.meta.env.PUBLIC_SENTRY_DSN, ... })into every SSR page throughinjectScript('page-ssr', ...). In this app that builds asdsn: void 0, and this init disables the transport. - The integration does not add the Cloudflare plugin. For Workers builds,
packages/astro/src/integration/index.tsadds its ownsentryCloudflareVitePlugin()from./cloudflare. That plugin wrapsastrojs-ssr-virtual-entry, which@astrojs/cloudflarev13 no longer has, and it always passes() => undefinedas the options. The user must add@sentry/cloudflare/viteby hand. - Two orchestrion plugins. The integration adds
sentryOrchestrionPlugin()for Workers, and@sentry/cloudflare/viteadds another one (with the workerd-safedcModule). With both, the build-time instrumentation runs twice.
Proposed fix
- For Cloudflare Workers builds, add
sentryCloudflareVitePlugin()from@sentry/cloudflare/vitein place of the integration's own Cloudflare and orchestrion plugins. - Do not inject the default server init snippet on Workers. The
withSentrywrap does the init frominstrument.server.*, or fromenvwhen there is no such file. - Keep
sentry.server.config.*working for apps that still use it asmain, because the auto-instrument plugin leaves an entry that is already wrapped alone. - Update
astro-6-cf-workers(andastro-5-cf-workersif it applies): removesentry.server.config.js, addinstrument.server.jswithdefineCloudflareOptions, and setmainto@astrojs/cloudflare/entrypoints/server.
Notes
@astrojs/cloudflarev13 setsmainto@astrojs/cloudflare/entrypoints/serverwhen the wrangler config has none (cloudflareConfigCustomizerin itsdist/wrangler.js).- Its
server.jsends withexport { server_default as default }. @sentry/cloudflare/vite: Auto-instrumentation skips the Worker when wranglermainis a package specifier #24522 adds support for that export form to the auto-instrument transform. - Check
astro devtoo: the integration only adds its Workers plugin whencommand !== 'dev', and@sentry/cloudflare/viteinstrumentsvite devas well.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
javascriptPull requests that update javascript codePull requests that update javascript code
Activity
linear-code commentedon Oct 14, 2026
JS-3934
fix(astro): defer to `@sentry/cloudflare/vite` on Cloudflare Workers (#…