Skip to content

@sentry/astro: Use the Cloudflare Vite plugin for Workers builds #25344

Closed

Description

@isaacs

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.

  1. Default server init with no DSN. With no sentry.server.config.* file, the integration falls back to buildServerSnippet() (packages/astro/src/integration/snippets.ts). It injects Sentry.init({ dsn: import.meta.env.PUBLIC_SENTRY_DSN, ... }) into every SSR page through injectScript('page-ssr', ...). In this app that builds as dsn: void 0, and this init disables the transport.
  2. The integration does not add the Cloudflare plugin. For Workers builds, packages/astro/src/integration/index.ts adds its own sentryCloudflareVitePlugin() from ./cloudflare. That plugin wraps astrojs-ssr-virtual-entry, which @astrojs/cloudflare v13 no longer has, and it always passes () => undefined as the options. The user must add @sentry/cloudflare/vite by hand.
  3. Two orchestrion plugins. The integration adds sentryOrchestrionPlugin() for Workers, and @sentry/cloudflare/vite adds another one (with the workerd-safe dcModule). With both, the build-time instrumentation runs twice.

Proposed fix

  • For Cloudflare Workers builds, add sentryCloudflareVitePlugin() from @sentry/cloudflare/vite in place of the integration's own Cloudflare and orchestrion plugins.
  • Do not inject the default server init snippet on Workers. The withSentry wrap does the init from instrument.server.*, or from env when there is no such file.
  • Keep sentry.server.config.* working for apps that still use it as main, because the auto-instrument plugin leaves an entry that is already wrapped alone.
  • Update astro-6-cf-workers (and astro-5-cf-workers if it applies): remove sentry.server.config.js, add instrument.server.js with defineCloudflareOptions, and set main to @astrojs/cloudflare/entrypoints/server.

Notes

Activity

  1. self-assigned this
    on Oct 14, 2026
  2. linear-code commented on Oct 14, 2026

    @linear-code
  3. added
    javascriptPull requests that update javascript code
    on Oct 14, 2026
  4. added a commit that references this issue on Oct 15, 2026
    0778826
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

javascriptPull requests that update javascript code

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions