diff --git a/dev-packages/e2e-tests/test-applications/astro-5/sentry.client.config.js b/dev-packages/e2e-tests/test-applications/astro-5/sentry.client.config.js
index 7bb40f0c60d4..865bb18ce84c 100644
--- a/dev-packages/e2e-tests/test-applications/astro-5/sentry.client.config.js
+++ b/dev-packages/e2e-tests/test-applications/astro-5/sentry.client.config.js
@@ -5,5 +5,17 @@ Sentry.init({
environment: 'qa',
tracesSampleRate: 1.0,
tunnel: 'http://localhost:3031/', // proxy server
- integrations: [Sentry.browserTracingIntegration()],
+ integrations: [
+ Sentry.browserTracingIntegration({
+ beforeStartSpan: opts => {
+ if (opts.name.startsWith('/blog/')) {
+ return {
+ ...opts,
+ name: window.location.pathname,
+ };
+ }
+ return opts;
+ },
+ }),
+ ],
});
diff --git a/dev-packages/e2e-tests/test-applications/astro-5/src/pages/blog/[slug].astro b/dev-packages/e2e-tests/test-applications/astro-5/src/pages/blog/[slug].astro
new file mode 100644
index 000000000000..b776fa25c494
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/astro-5/src/pages/blog/[slug].astro
@@ -0,0 +1,11 @@
+---
+import Layout from '../../layouts/Layout.astro';
+
+export const prerender = false;
+
+const { slug } = Astro.params;
+---
+
+
+ Blog post: {slug}
+
diff --git a/dev-packages/e2e-tests/test-applications/astro-5/src/pages/index.astro b/dev-packages/e2e-tests/test-applications/astro-5/src/pages/index.astro
index e598994f0b8e..7032437764f8 100644
--- a/dev-packages/e2e-tests/test-applications/astro-5/src/pages/index.astro
+++ b/dev-packages/e2e-tests/test-applications/astro-5/src/pages/index.astro
@@ -17,6 +17,7 @@ import Layout from '../layouts/Layout.astro';
Static Page
Server Island
Test Parametrized Routes
+ Route Parametrization override
diff --git a/dev-packages/e2e-tests/test-applications/astro-5/tests/tracing.dynamic.test.ts b/dev-packages/e2e-tests/test-applications/astro-5/tests/tracing.dynamic.test.ts
index b7dda807c65c..9151c13907af 100644
--- a/dev-packages/e2e-tests/test-applications/astro-5/tests/tracing.dynamic.test.ts
+++ b/dev-packages/e2e-tests/test-applications/astro-5/tests/tracing.dynamic.test.ts
@@ -369,4 +369,18 @@ test.describe('parametrized vs static paths', () => {
request: { url: expect.stringContaining('/user-page/settings') },
});
});
+
+ test('allows for span name override via beforeStartSpan', async ({ page }) => {
+ const clientPageloadTxnPromise = waitForTransaction('astro-5', txnEvent => {
+ return txnEvent?.transaction?.startsWith('/blog/') ?? false;
+ });
+
+ await page.goto('/blog/my-post');
+
+ const clientPageloadTxn = await clientPageloadTxnPromise;
+ expect(clientPageloadTxn).toMatchObject({
+ transaction: '/blog/my-post',
+ transaction_info: { source: 'custom' },
+ });
+ });
});
diff --git a/packages/astro/src/client/browserTracingIntegration.ts b/packages/astro/src/client/browserTracingIntegration.ts
index 7f8576671635..5ffdb3fd8860 100644
--- a/packages/astro/src/client/browserTracingIntegration.ts
+++ b/packages/astro/src/client/browserTracingIntegration.ts
@@ -1,6 +1,15 @@
-import { browserTracingIntegration as originalBrowserTracingIntegration, WINDOW } from '@sentry/browser';
+import {
+ browserTracingIntegration as originalBrowserTracingIntegration,
+ startBrowserTracingPageLoadSpan,
+ WINDOW,
+} from '@sentry/browser';
import type { Integration, TransactionSource } from '@sentry/core';
-import { debug, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core';
+import {
+ browserPerformanceTimeOrigin,
+ debug,
+ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
+ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
+} from '@sentry/core';
import { DEBUG_BUILD } from '../debug-build';
/**
@@ -18,35 +27,53 @@ function getMetaContent(metaName: string): string | undefined {
export function browserTracingIntegration(
options: Parameters[0] = {},
): Integration {
- const integration = originalBrowserTracingIntegration(options);
+ const integration = originalBrowserTracingIntegration({ ...options, instrumentPageLoad: false });
return {
...integration,
- setup(client) {
- // Original integration setup call
- integration.setup?.(client);
-
- client.on('afterStartPageLoadSpan', pageLoadSpan => {
- const routeNameFromMetaTags = getMetaContent('sentry-route-name');
-
- if (routeNameFromMetaTags) {
- let decodedRouteName;
- try {
- decodedRouteName = decodeURIComponent(routeNameFromMetaTags);
- } catch {
- // We ignore errors here, e.g. if the value cannot be URL decoded.
- return;
- }
-
- DEBUG_BUILD && debug.log(`[Tracing] Using route name from Sentry HTML meta-tag: ${decodedRouteName}`);
-
- pageLoadSpan.updateName(decodedRouteName);
- pageLoadSpan.setAttributes({
- [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route' as TransactionSource,
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.astro',
+ afterAllSetup(client) {
+ // Original integration afterAllSetup call
+ integration.afterAllSetup?.(client);
+
+ if (WINDOW.location) {
+ if (options.instrumentPageLoad != false) {
+ const origin = browserPerformanceTimeOrigin();
+
+ const { name, source } = getPageloadSpanName();
+
+ startBrowserTracingPageLoadSpan(client, {
+ name,
+ // pageload should always start at timeOrigin (and needs to be in s, not ms)
+ startTime: origin ? origin / 1000 : undefined,
+ attributes: {
+ [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.astro',
+ },
});
}
- });
+ }
},
};
}
+
+function getPageloadSpanName(): { name: string; source: TransactionSource } {
+ try {
+ const routeNameFromMetaTags = getMetaContent('sentry-route-name');
+ if (routeNameFromMetaTags) {
+ const decodedRouteName = decodeURIComponent(routeNameFromMetaTags);
+
+ DEBUG_BUILD && debug.log(`[Tracing] Using route name from Sentry HTML meta-tag: ${decodedRouteName}`);
+
+ return {
+ name: decodedRouteName,
+ source: 'route',
+ };
+ }
+ } catch {
+ // fail silently if decoding or reading the meta tag fails
+ }
+ return {
+ name: WINDOW.location.pathname,
+ source: 'url',
+ };
+}