Official Support for React Router v7 Framework Mode in dd-trace-js #5474
jdnichollsc
started this conversation in
Ideas
Replies: 2 comments 1 reply
-
This is my workaround <3 import { RouteConfigEntry } from "@react-router/dev/routes";
import { matchRoutes } from "react-router";
import routes from "@/routes";
import tracer, { DD_TRACER_SERVICE_NAME } from "@/tracer";
// Extract the type from matchRoutes function parameter
type AgnosticRouteObject = Parameters<typeof matchRoutes>[0][0];
export function convertRouteConfig(entries: RouteConfigEntry[]): AgnosticRouteObject[] {
return entries.map((entry) => {
const routeObj: AgnosticRouteObject = {
index: entry.index,
path: entry.path,
caseSensitive: entry.caseSensitive,
id: entry.id,
};
if (entry.children) {
routeObj.children = convertRouteConfig(entry.children);
}
return routeObj;
});
}
tracer.use("express", {
enabled: true,
service: DD_TRACER_SERVICE_NAME,
hooks: {
request: (span, req, res) => {
const host = req?.headers.host;
// React Router adds .data to the URL sometimes, so we need to remove it
const path = req?.url?.replace(".data", "");
if (span && req?.url) {
try {
const url = new URL(`https://${host}${path}`);
if (req.headers["x-correlation-id"]) {
span.setTag("correlation_id", req.headers["x-correlation-id"]);
}
span.setTag("path", url.pathname);
span.setTag("method", req.method);
span.setTag("http.url", url.toString());
const matches = matchRoutes(convertRouteConfig(routes), url.pathname);
if (matches?.length) {
span.setTag("http.route", matches?.at(-1)?.route.path);
}
if (res?.statusCode) {
span.setTag("http.status_code", res?.statusCode);
}
} catch (error) {
logger.error(error, "Error setting tags for Datadog");
}
}
},
},
});
/**
*
* This file is dedicated to initializing Datadog tracing early—before any other instrumented module is imported.
*
*/
import ddTrace from "dd-trace";
export const DD_TRACER_SERVICE_NAME = process.env.DD_SERVICE ?? "web-app";
export const tracer = ddTrace.init({
env: process.env.APP_ENV,
version: process.env.APP_VERSION,
service: DD_TRACER_SERVICE_NAME,
sampleRate: process.env.NODE_ENV === "production" ? 0.5 : 1,
logInjection: process.env.DD_LOGS_INJECTION !== "false",
plugins: false,
});
tracer.use("http", {
service: `${DD_TRACER_SERVICE_NAME}.http`,
});
tracer.use("pino", {
enabled: true,
service: DD_TRACER_SERVICE_NAME,
});
export default tracer;
"dev": "cross-env NODE_ENV=development DD_TRACE_ESM_REQUIRE=true NODE_OPTIONS='--enable-source-maps --inspect --import dd-trace/register.js --import ./app/tracer.js' node server.js" |
Beta Was this translation helpful? Give feedback.
0 replies
-
@jdnichollsc please open an issue for this. We are soon going to close the discussions section. |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Summary
We request that Datadog extend dd-trace-js to officially support React Router v7’s Framework Mode. Currently, when using React Router v7 in a Remix-style application with a custom server (such as Express), the tracer fails to capture proper route information, resulting in all requests being grouped under a generic route (e.g. "/"). This limitation hinders route-level visibility in Datadog APM for modern full-stack React applications.
Background
React Router v7 in Framework Mode is used in modern React applications (e.g., Remix) to handle server-side rendering with a custom Express server. In this setup, the router is mounted as a catch-all middleware, which prevents Datadog’s Express integration from intercepting and tagging individual routes correctly.
Several discussions in the dd-trace-js repository (for instance, this comment) have highlighted that:
Proposed Solution
We propose that Datadog implement an integration for React Router v7 Framework Mode in dd-trace-js by:
Detecting the Framework Mode:
Recognize when an Express app is running React Router v7 in Framework Mode.
Extracting Route Information:
Utilize React Router’s internals or a route manifest to derive the correct route pattern (e.g.,
/users/:id
) and automatically set it as the span’s resource name orhttp.route
tag.Reference Implementation:
Use the official template provided by the React Router team as a guide for the integration. For instance, the custom server template available here can serve as a starting point:
React Router Custom Server Template
Benefits
Enhanced Route-Level Visibility:
Developers will see accurate, meaningful route names in their traces instead of a generic “/” endpoint.
Improved Developer Experience:
Official support will eliminate the need for custom workarounds or third-party libraries, reducing complexity and maintenance overhead.
Broader Ecosystem Support:
With many teams adopting React Router v7 in Remix-style apps, this integration would ensure that Datadog APM remains a robust solution for monitoring modern full-stack React applications.
Conclusion
Official support for React Router v7 Framework Mode in dd-trace-js will significantly enhance route-level tracing for modern React applications, enabling better performance monitoring and error diagnosis. We appreciate your consideration of this feature request and look forward to seeing improved integration for React Router v7 in future releases of dd-trace-js.
Thank you for your time and support! <3
Beta Was this translation helpful? Give feedback.
All reactions