@@ -6,7 +6,7 @@ import React from 'react';
6
6
import { PageAside } from '@/components/PageAside' ;
7
7
import { PageBody , PageCover } from '@/components/PageBody' ;
8
8
import { PageHrefContext , absoluteHref , pageHref } from '@/lib/links' ;
9
- import { getPagePath } from '@/lib/pages' ;
9
+ import { getPagePath , resolveFirstDocument } from '@/lib/pages' ;
10
10
import { ContentRefContext } from '@/lib/references' ;
11
11
import { tcls } from '@/lib/tailwind' ;
12
12
import { getContentTitle } from '@/lib/utils' ;
@@ -19,10 +19,12 @@ export const runtime = 'edge';
19
19
/**
20
20
* Fetch and render a page.
21
21
*/
22
- export default async function Page ( props : { params : PagePathParams } ) {
23
- const { params } = props ;
22
+ export default async function Page ( props : {
23
+ params : PagePathParams ;
24
+ searchParams : { fallback ?: string } ;
25
+ } ) {
26
+ const { params, searchParams } = props ;
24
27
25
- const rawPathname = getPathnameParam ( params ) ;
26
28
const {
27
29
content : contentPointer ,
28
30
contentTarget,
@@ -32,9 +34,14 @@ export default async function Page(props: { params: PagePathParams }) {
32
34
pages,
33
35
page,
34
36
document,
35
- } = await fetchPageData ( params ) ;
36
- const linksContext : PageHrefContext = { } ;
37
+ } = await getPageDataWithFallback ( {
38
+ pagePathParams : params ,
39
+ searchParams,
40
+ redirectOnFallback : true ,
41
+ } ) ;
37
42
43
+ const linksContext : PageHrefContext = { } ;
44
+ const rawPathname = getPathnameParam ( params ) ;
38
45
if ( ! page ) {
39
46
const pathname = normalizePathname ( rawPathname ) ;
40
47
if ( pathname !== rawPathname ) {
@@ -114,8 +121,18 @@ export async function generateViewport({ params }: { params: PagePathParams }):
114
121
} ;
115
122
}
116
123
117
- export async function generateMetadata ( { params } : { params : PagePathParams } ) : Promise < Metadata > {
118
- const { space, pages, page, customization, parent } = await fetchPageData ( params ) ;
124
+ export async function generateMetadata ( {
125
+ params,
126
+ searchParams,
127
+ } : {
128
+ params : PagePathParams ;
129
+ searchParams : { fallback ?: string } ;
130
+ } ) : Promise < Metadata > {
131
+ const { space, pages, page, customization, parent } = await getPageDataWithFallback ( {
132
+ pagePathParams : params ,
133
+ searchParams,
134
+ } ) ;
135
+
119
136
if ( ! page ) {
120
137
notFound ( ) ;
121
138
}
@@ -136,3 +153,34 @@ export async function generateMetadata({ params }: { params: PagePathParams }):
136
153
} ,
137
154
} ;
138
155
}
156
+
157
+ /**
158
+ * Fetches the page data matching the requested pathname and fallback to root page when page is not found.
159
+ */
160
+ async function getPageDataWithFallback ( args : {
161
+ pagePathParams : PagePathParams ;
162
+ searchParams : { fallback ?: string } ;
163
+ redirectOnFallback ?: boolean ;
164
+ } ) {
165
+ const { pagePathParams, searchParams, redirectOnFallback = false } = args ;
166
+
167
+ const { pages, page : targetPage , ...otherPageData } = await fetchPageData ( pagePathParams ) ;
168
+
169
+ let page = targetPage ;
170
+ const canFallback = ! ! searchParams . fallback ;
171
+ if ( ! page && canFallback ) {
172
+ const rootPage = resolveFirstDocument ( pages , [ ] ) ;
173
+
174
+ if ( redirectOnFallback && rootPage ?. page ) {
175
+ redirect ( pageHref ( pages , rootPage ?. page ) ) ;
176
+ }
177
+
178
+ page = rootPage ?. page ;
179
+ }
180
+
181
+ return {
182
+ ...otherPageData ,
183
+ pages,
184
+ page,
185
+ } ;
186
+ }
0 commit comments