Skip to content

Commit 8295f1d

Browse files
authored
feat(react-router): Add server action instrumentation (#16292)
1 parent e00cb04 commit 8295f1d

File tree

4 files changed

+53
-1
lines changed

4 files changed

+53
-1
lines changed

dev-packages/e2e-tests/test-applications/react-router-7-framework/app/routes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@ export default [
1616
route('with/:param', 'routes/performance/dynamic-param.tsx'),
1717
route('static', 'routes/performance/static.tsx'),
1818
route('server-loader', 'routes/performance/server-loader.tsx'),
19+
route('server-action', 'routes/performance/server-action.tsx'),
1920
]),
2021
] satisfies RouteConfig;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Form } from 'react-router';
2+
import type { Route } from './+types/server-action';
3+
4+
export async function action({ request }: Route.ActionArgs) {
5+
let formData = await request.formData();
6+
let name = formData.get('name');
7+
await new Promise(resolve => setTimeout(resolve, 1000));
8+
return {
9+
greeting: `Hola ${name}`,
10+
};
11+
}
12+
13+
export default function Project({ actionData }: Route.ComponentProps) {
14+
return (
15+
<div>
16+
<h1>Server action page</h1>
17+
<Form method="post">
18+
<input type="text" name="name" />
19+
<button type="submit">Submit</button>
20+
</Form>
21+
{actionData ? <p>{actionData.greeting}</p> : null}
22+
</div>
23+
);
24+
}

dev-packages/e2e-tests/test-applications/react-router-7-framework/tests/performance/performance.server.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,31 @@ test.describe('servery - performance', () => {
132132
origin: 'auto.http.react-router',
133133
});
134134
});
135+
136+
test('should automatically instrument server action', async ({ page }) => {
137+
const txPromise = waitForTransaction(APP_NAME, async transactionEvent => {
138+
return transactionEvent.transaction === 'POST /performance/server-action.data';
139+
});
140+
141+
await page.goto(`/performance/server-action`);
142+
await page.getByRole('button', { name: 'Submit' }).click(); // this will trigger a .data request
143+
144+
const transaction = await txPromise;
145+
146+
expect(transaction?.spans?.[transaction.spans?.length - 1]).toMatchObject({
147+
span_id: expect.any(String),
148+
trace_id: expect.any(String),
149+
data: {
150+
'sentry.origin': 'auto.http.react-router',
151+
'sentry.op': 'function.react-router.action',
152+
},
153+
description: 'Executing Server Action',
154+
parent_span_id: expect.any(String),
155+
start_timestamp: expect.any(Number),
156+
timestamp: expect.any(Number),
157+
status: 'ok',
158+
op: 'function.react-router.action',
159+
origin: 'auto.http.react-router',
160+
});
161+
});
135162
});

packages/react-router/src/server/sdk.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export function init(options: NodeOptions): NodeClient | undefined {
4545
const overwrite = event.contexts?.trace?.data?.[SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE];
4646
if (
4747
event.type === 'transaction' &&
48-
event.transaction === 'GET *' &&
48+
(event.transaction === 'GET *' || event.transaction === 'POST *') &&
4949
event.contexts?.trace?.data?.[ATTR_HTTP_ROUTE] === '*' &&
5050
overwrite
5151
) {

0 commit comments

Comments
 (0)