@@ -2,6 +2,30 @@ import { logger } from '@sentry/core';
22import type { NuxtSSRContext } from 'nuxt/app' ;
33import type { NuxtPage } from 'nuxt/schema' ;
44
5+ export type NuxtPageSubset = { path : NuxtPage [ 'path' ] ; file : NuxtPage [ 'file' ] } ;
6+
7+ // buildTimePagesData -> Map<file, path>
8+ const routeMappingCache = new WeakMap < NuxtPageSubset [ ] , Map < string , string > > ( ) ;
9+
10+ /**
11+ * Creates a mapping from module paths to parametrized routes for faster lookup.
12+ * The `buildTimePagesData` doesn't change during SSR, as it's generated at build time.
13+ */
14+ function createRouteMapping ( buildTimePagesData : NuxtPageSubset [ ] ) : Map < string , string > {
15+ const mapping = new Map < string , string > ( ) ;
16+
17+ for ( const routeData of buildTimePagesData ) {
18+ if ( routeData . file && routeData . path ) {
19+ // Handle Unix and Windows paths
20+ const normalizedFile = routeData . file . replace ( / \\ / g, '/' ) ;
21+ mapping . set ( normalizedFile , routeData . path ) ;
22+ }
23+ }
24+
25+ routeMappingCache . set ( buildTimePagesData , mapping ) ;
26+ return mapping ;
27+ }
28+
529/**
630 * Extracts route information from the SSR context modules and URL.
731 *
@@ -17,12 +41,12 @@ import type { NuxtPage } from 'nuxt/schema';
1741 *
1842 * @param buildTimePagesData
1943 * An array of NuxtPage objects representing the build-time pages data.
20- * Example: [{ name : 'some- path', path: '/some/path' }, { name : 'user- userId', path: '/user/:userId()' }]
44+ * Example: [{ file : '/a/file/pages/ some/ path', path: '/some/path' }, { file : '/a/file/pages/ user/[ userId].vue ', path: '/user/:userId()' }]
2145 */
2246export function extractParametrizedRouteFromContext (
2347 ssrContextModules ?: NuxtSSRContext [ 'modules' ] ,
2448 currentUrl ?: NuxtSSRContext [ 'url' ] ,
25- buildTimePagesData : NuxtPage [ ] = [ ] ,
49+ buildTimePagesData : NuxtPageSubset [ ] = [ ] ,
2650) : null | { parametrizedRoute : string } {
2751 if ( ! ssrContextModules || ! currentUrl ) {
2852 logger . warn ( 'SSR context modules or URL is not available.' ) ;
@@ -35,30 +59,24 @@ export function extractParametrizedRouteFromContext(
3559
3660 const modulesArray = Array . from ( ssrContextModules ) ;
3761
38- // Find the route data that corresponds to a module in ssrContext.modules
39- const foundRouteData = buildTimePagesData . find ( routeData => {
40- if ( ! routeData . file ) return false ;
41-
42- return modulesArray . some ( module => {
43- // Extract the folder name and relative path from the page file
44- // e.g., 'pages/test-param/[param].vue' -> folder: 'pages', path: 'test-param/[param].vue'
45- const filePathParts = module . split ( '/' ) ;
62+ const existingRouteMapping = routeMappingCache . get ( buildTimePagesData ) ;
63+ const routeMapping = existingRouteMapping || createRouteMapping ( buildTimePagesData ) ;
4664
47- // Exclude root-level files (e.g., 'app.vue')
48- if ( filePathParts . length < 2 ) return false ;
65+ const modulePagePaths = modulesArray . map ( module => {
66+ const filePathParts = module . split ( '/' ) ;
67+ if ( filePathParts . length < 2 ) return null ;
4968
50- // Normalize path separators to handle both Unix and Windows paths
51- const normalizedRouteFile = routeData . file ?. replace ( / \\ / g, '/' ) ;
52-
53- const pagesFolder = filePathParts [ 0 ] ;
54- const pageRelativePath = filePathParts . slice ( 1 ) . join ( '/' ) ;
55-
56- // Check if any module in ssrContext.modules ends with the same folder/relative path structure
57- return normalizedRouteFile ?. endsWith ( `/${ pagesFolder } /${ pageRelativePath } ` ) ;
58- } ) ;
69+ const pagesFolder = filePathParts [ 0 ] ;
70+ const pageRelativePath = filePathParts . slice ( 1 ) . join ( '/' ) ;
71+ return `/${ pagesFolder } /${ pageRelativePath } ` ;
5972 } ) ;
6073
61- const parametrizedRoute = foundRouteData ?. path ?? null ;
74+ for ( const [ pageFile , route ] of routeMapping ) {
75+ // Check if any module of the requested page ends with the same folder/relative path structure as the parametrized filePath from build time.
76+ if ( modulePagePaths . some ( filePath => filePath && pageFile . endsWith ( filePath ) ) ) {
77+ return { parametrizedRoute : route } ;
78+ }
79+ }
6280
63- return parametrizedRoute === null ? null : { parametrizedRoute } ;
81+ return null ;
6482}
0 commit comments