@@ -48,6 +48,7 @@ function buildRegexForDynamicRoute(routePath: string): { pattern: string; paramN
48
48
const segments = routePath . split ( '/' ) . filter ( Boolean ) ;
49
49
const regexSegments : string [ ] = [ ] ;
50
50
const paramNames : string [ ] = [ ] ;
51
+ let hasOptionalCatchall = false ;
51
52
52
53
for ( const segment of segments ) {
53
54
if ( segment . startsWith ( ':' ) ) {
@@ -57,7 +58,8 @@ function buildRegexForDynamicRoute(routePath: string): { pattern: string; paramN
57
58
// Optional catchall: matches zero or more segments
58
59
const cleanParamName = paramName . slice ( 0 , - 2 ) ;
59
60
paramNames . push ( cleanParamName ) ;
60
- regexSegments . push ( '(.*)' ) ;
61
+ // Handling this special case in pattern construction below
62
+ hasOptionalCatchall = true ;
61
63
} else if ( paramName . endsWith ( '*' ) ) {
62
64
// Required catchall: matches one or more segments
63
65
const cleanParamName = paramName . slice ( 0 , - 1 ) ;
@@ -74,7 +76,16 @@ function buildRegexForDynamicRoute(routePath: string): { pattern: string; paramN
74
76
}
75
77
}
76
78
77
- const pattern = `^/${ regexSegments . join ( '/' ) } $` ;
79
+ let pattern : string ;
80
+ if ( hasOptionalCatchall ) {
81
+ // For optional catchall, make the trailing slash and segments optional
82
+ // This allows matching both /catchall and /catchall/anything
83
+ const staticParts = regexSegments . join ( '/' ) ;
84
+ pattern = `^/${ staticParts } (?:/(.*))?$` ;
85
+ } else {
86
+ pattern = `^/${ regexSegments . join ( '/' ) } $` ;
87
+ }
88
+
78
89
return { pattern, paramNames } ;
79
90
}
80
91
0 commit comments