@@ -2,6 +2,7 @@ import type { GitBookSiteContext } from '@v2/lib/context';
2
2
import { redirect } from 'next/navigation' ;
3
3
4
4
import { resolvePageId , resolvePagePath } from '@/lib/pages' ;
5
+ import { withLeadingSlash } from '@/lib/paths' ;
5
6
import { getDataOrNull } from '@v2/lib/data' ;
6
7
7
8
export interface PagePathParams {
@@ -35,14 +36,14 @@ export async function fetchPageData(context: GitBookSiteContext, params: PagePar
35
36
* If the path can't be found, we try to resolve it from the API to handle redirects.
36
37
*/
37
38
async function resolvePage ( context : GitBookSiteContext , params : PagePathParams | PageIdParams ) {
38
- const { organizationId, site, space, revisionId, pages, shareKey } = context ;
39
+ const { organizationId, site, space, revisionId, pages, shareKey, linker } = context ;
39
40
40
41
if ( 'pageId' in params ) {
41
42
return resolvePageId ( pages , params . pageId ) ;
42
43
}
43
44
44
45
const rawPathname = getPathnameParam ( params ) ;
45
- const pathname = normalizePathname ( rawPathname ) ;
46
+ const pathname = rawPathname . toLowerCase ( ) ;
46
47
47
48
// When resolving a page, we use the lowercased pathname
48
49
const page = resolvePagePath ( pages , pathname ) ;
@@ -67,16 +68,26 @@ async function resolvePage(context: GitBookSiteContext, params: PagePathParams |
67
68
}
68
69
69
70
// If a page still can't be found, we try with the API, in case we have a redirect at site level.
70
- const resolvedSiteRedirect = await getDataOrNull (
71
- context . dataFetcher . getSiteRedirectBySource ( {
72
- organizationId,
73
- siteId : site . id ,
74
- source : rawPathname . startsWith ( '/' ) ? rawPathname : `/${ rawPathname } ` ,
75
- siteShareKey : shareKey ,
76
- } )
77
- ) ;
78
- if ( resolvedSiteRedirect ) {
79
- return redirect ( resolvedSiteRedirect . target ) ;
71
+ const redirectSources = [
72
+ // Test the pathname relative to the root
73
+ // For example hello/world -> section/variant/hello/world
74
+ withLeadingSlash ( linker . toRelativePathInSite ( linker . toPathInSpace ( rawPathname ) ) ) ,
75
+ // Test the pathname relative to the content/space
76
+ // For example hello/world -> /hello/world
77
+ withLeadingSlash ( rawPathname ) ,
78
+ ] ;
79
+ for ( const source of redirectSources ) {
80
+ const resolvedSiteRedirect = await getDataOrNull (
81
+ context . dataFetcher . getSiteRedirectBySource ( {
82
+ organizationId,
83
+ siteId : site . id ,
84
+ source,
85
+ siteShareKey : shareKey ,
86
+ } )
87
+ ) ;
88
+ if ( resolvedSiteRedirect ) {
89
+ return redirect ( resolvedSiteRedirect . target ) ;
90
+ }
80
91
}
81
92
}
82
93
@@ -99,10 +110,3 @@ export function getPathnameParam(params: PagePathParams): string {
99
110
100
111
return pathname . map ( ( part ) => decodeURIComponent ( part ) ) . join ( '/' ) ;
101
112
}
102
-
103
- /**
104
- * Normalize the URL pathname into the format used in the revision page path.
105
- */
106
- export function normalizePathname ( pathname : string ) {
107
- return pathname . toLowerCase ( ) ;
108
- }
0 commit comments