@@ -130,6 +130,39 @@ async function generateResult(
130130 } ;
131131}
132132
133+ /**
134+ *
135+ * https://github.com/vercel/next.js/blob/34039551d2e5f611c0abde31a197d9985918adaf/packages/next/src/shared/lib/router/utils/escape-path-delimiters.ts#L2-L10
136+ */
137+ function escapePathDelimiters (
138+ segment : string ,
139+ escapeEncoded ?: boolean ,
140+ ) : string {
141+ return segment . replace (
142+ new RegExp ( `([/#?]${ escapeEncoded ? "|%(2f|23|3f|5c)" : "" } )` , "gi" ) ,
143+ ( char : string ) => encodeURIComponent ( char ) ,
144+ ) ;
145+ }
146+
147+ /**
148+ *
149+ * SSG cache key needs to be decoded, but some characters needs to be properly escaped
150+ * https://github.com/vercel/next.js/blob/34039551d2e5f611c0abde31a197d9985918adaf/packages/next/src/server/lib/router-utils/decode-path-params.ts#L11-L26
151+ */
152+ function decodePathParams ( pathname : string ) : string {
153+ return pathname
154+ . split ( "/" )
155+ . map ( ( segment ) => {
156+ try {
157+ return escapePathDelimiters ( decodeURIComponent ( segment ) , true ) ;
158+ } catch ( e ) {
159+ // If decodeURIComponent fails, we return the original segment
160+ return segment ;
161+ }
162+ } )
163+ . join ( "/" ) ;
164+ }
165+
133166export async function cacheInterceptor (
134167 event : InternalEvent ,
135168) : Promise < InternalEvent | InternalResult > {
@@ -147,6 +180,9 @@ export async function cacheInterceptor(
147180 // We also need to remove trailing slash
148181 localizedPath = localizedPath . replace ( / \/ $ / , "" ) ;
149182
183+ // Then we decode the path params
184+ localizedPath = decodePathParams ( localizedPath ) ;
185+
150186 debug ( "Checking cache for" , localizedPath , PrerenderManifest ) ;
151187
152188 const isISR =
0 commit comments