Skip to content

Conversation

@onurtemizkan
Copy link
Collaborator

@onurtemizkan onurtemizkan commented Oct 16, 2025

This PR adds parameterized routes for Remix SDK, similarly to the NextJS SDK

Resolves: #16690
Needs docs PR for the Vite plugin

Adds automatic parameterization of Remix route IDs for transaction naming. Converts internal Remix route file patterns to parameterized paths similar to the other SDKs (routes/user.$id -> /user/:id).

  • Created sentryRemixVitePlugin that extracts route information from Remix builds and generates a manifest file containing route ID to parameterized route mappings.
  • Added remixRouteParameterization.ts with regex-based route conversion that handles dynamic segments ($param:param), splat routes ($:*), and nested routes.
  • Updated both client and server instrumentation in performance.tsx and instrumentServer.ts to use parameterized transaction names.
  • It also works with Hydrogen

Vite plugin is used like:

// vite.config.ts
import { defineConfig } from 'vite';
import { vitePlugin as remix } from '@remix-run/dev';
import { sentryRemixVitePlugin } from '@sentry/remix';

export default defineConfig({
  plugins: [
    remix(),
    sentryRemixVitePlugin({
      appDirPath: './app', // Default is 'app' in project root
    }),
  ],
});

Updated all Remix E2E test applications to expect parameterized route names. Added new E2E test application create-remix-app-v2-non-vite for testing backward compatibility for non-Vite builds - these continue to use routes/user.$id format.

Summary

Route File Example URL Before After (Vite only)
_index.tsx / routes/_index /
user.$id.tsx /user/123 routes/user.$id /user/:id
users.$userId.posts.$postId.tsx /users/123/posts/456 routes/users.$userId.posts.$postId /users/:userId/posts/:postId
$.tsx (splat) /docs/guide/intro routes/$ /:*
docs.$.tsx (scoped splat) /docs/guide/intro routes/docs.$ /docs/:*
  • Legacy Remix applications (non-Vite) will continue to work without changes.
  • For backward compatibility, Vite projects that are not using the plugin will behave like before.

@onurtemizkan onurtemizkan force-pushed the onur/remix-parameterized-routes branch from 0460a75 to 8886ddc Compare October 16, 2025 12:17
@onurtemizkan onurtemizkan marked this pull request as ready for review October 16, 2025 14:06
cursor[bot]

This comment was marked as outdated.

@github-actions
Copy link
Contributor

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

Scenario Requests/s % of Baseline Prev. Requests/s Change %
GET Baseline 8,965 - 9,344 -4%
GET With Sentry 1,325 15% 1,412 -6%
GET With Sentry (error only) 5,924 66% 6,130 -3%
POST Baseline 1,189 - 1,211 -2%
POST With Sentry 504 42% 509 -1%
POST With Sentry (error only) 1,033 87% 1,069 -3%
MYSQL Baseline 3,240 - 3,221 +1%
MYSQL With Sentry 455 14% 370 +23%
MYSQL With Sentry (error only) 2,659 82% 2,625 +1%

View base workflow run

if: needs.job_build.outputs.changed_remix == 'true' || github.event_name != 'pull_request'
runs-on: ubuntu-24.04
timeout-minutes: 10
timeout-minutes: 15
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did this increase so much?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After adding the new tests, some of them started randomly timing out slightly above the 10-minute threshold on CI. It can be 11-12. I just increased this much to be ready for when we add more tests.


// No manifest available (legacy app without Vite plugin)
// Fall back to route ID for backward compatibility
return { name: routeId, source: 'route' };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be url here then? In the legacy case this will not be parameterized right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is still not an unparameterized url really, in the previous implementation we were using route for the routeId (e.g. routes/users.$userId.posts.$postId) as well, so while it's not a parameterized route by its format, it still contains the parameterized route info.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement parametrized routes for Remix Client

2 participants