Skip to content

Commit

Permalink
Added a proper name for generateMetadata
Browse files Browse the repository at this point in the history
  • Loading branch information
jankaifer committed Mar 21, 2023
1 parent 467600c commit 10e35db
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 33 deletions.
30 changes: 22 additions & 8 deletions packages/next/src/lib/metadata/resolve-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ function merge(

async function getDefinedMetadata(
mod: any,
props: any
props: any,
pathname: string
): Promise<Metadata | MetadataResolver | null> {
// Layer is a client component, we just skip it. It can't have metadata exported.
// Return early to avoid accessing properties error for client references.
Expand All @@ -196,7 +197,7 @@ async function getDefinedMetadata(
getTracer().trace(
ResolveMetadataSpan.generateMetadata,
{
spanName: `generateMetadata`,
spanName: `generateMetadata ${pathname}`,
},
() => mod.generateMetadata(props, parent)
)
Expand Down Expand Up @@ -240,14 +241,27 @@ async function resolveStaticMetadata(components: ComponentsType) {
}

// [layout.metadata, static files metadata] -> ... -> [page.metadata, static files metadata]
export async function collectMetadata(
loaderTree: LoaderTree,
props: any,
export async function collectMetadata({
loaderTree,
props,
array,
pathname,
}: {
loaderTree: LoaderTree
props: any
array: MetadataItems
) {
const mod = await getLayoutOrPageModule(loaderTree)
pathname: string
}) {
const [mod, modType] = await getLayoutOrPageModule(loaderTree)

if (modType) {
pathname += `/${modType}`
}

const staticFilesMetadata = await resolveStaticMetadata(loaderTree[2])
const metadataExport = mod ? await getDefinedMetadata(mod, props) : null
const metadataExport = mod
? await getDefinedMetadata(mod, props, pathname)
: null

array.push([metadataExport, staticFilesMetadata])
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { LoaderTree } from '../lib/app-dir-module'
import { FlightRouterState, Segment } from './types'
import { GetDynamicParamFromSegment } from './index'

// TODO-APP: Move __PAGE__ to a shared constant
const PAGE_SEGMENT_KEY = '__PAGE__'
import { PAGE_SEGMENT_KEY } from '../../shared/lib/constants'

export function addSearchParamsIfPageSegment(
segment: Segment,
Expand Down
57 changes: 40 additions & 17 deletions packages/next/src/server/app-render/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ import {
addSearchParamsIfPageSegment,
createFlightRouterStateFromLoaderTree,
} from './create-flight-router-state-from-loader-tree'
import { PAGE_SEGMENT_KEY } from '../../shared/lib/constants'

export const isEdgeRuntime = process.env.NEXT_RUNTIME === 'edge'

Expand Down Expand Up @@ -279,12 +280,21 @@ export async function renderToHTMLOrFlight(
}
}

async function resolveHead(
tree: LoaderTree,
parentParams: { [key: string]: any },
async function resolveHead({
tree,
parentParams,
metadataItems,
treePrefix = [],
}: {
tree: LoaderTree
parentParams: { [key: string]: any }
metadataItems: MetadataItems
): Promise<[React.ReactNode, MetadataItems]> {
/** Provided tree can be nested subtree, this argument says what is the path of such subtree */
treePrefix?: string[]
}): Promise<[React.ReactNode, MetadataItems]> {
const [segment, parallelRoutes, { head, page }] = tree
const currentTreePrefix = [...treePrefix, segment]
console.log(currentTreePrefix, tree)
const isPage = typeof page !== 'undefined'
// Handle dynamic segment params.
const segmentParam = getDynamicParamFromSegment(segment)
Expand All @@ -306,15 +316,24 @@ export async function renderToHTMLOrFlight(
...(isPage && searchParamsProps),
}

await collectMetadata(tree, layerProps, metadataItems)
await collectMetadata({
loaderTree: tree,
props: layerProps,
array: metadataItems,
pathname: currentTreePrefix
// __PAGE__ shouldn't be shown in a pathname
.filter((s) => s !== PAGE_SEGMENT_KEY)
.join('/'),
})

for (const key in parallelRoutes) {
const childTree = parallelRoutes[key]
const [returnedHead] = await resolveHead(
childTree,
currentParams,
metadataItems
)
const [returnedHead] = await resolveHead({
tree: childTree,
parentParams: currentParams,
metadataItems,
treePrefix: currentTreePrefix,
})
if (returnedHead) {
return [returnedHead, metadataItems]
}
Expand Down Expand Up @@ -473,7 +492,7 @@ export async function renderToHTMLOrFlight(

const isLayout = typeof layout !== 'undefined'
const isPage = typeof page !== 'undefined'
const layoutOrPageMod = await getLayoutOrPageModule(tree)
const [layoutOrPageMod] = await getLayoutOrPageModule(tree)

/**
* Checks if the current segment is a root layout.
Expand Down Expand Up @@ -979,11 +998,11 @@ export async function renderToHTMLOrFlight(
return [actualSegment]
}

const [resolvedHead, metadataItems] = await resolveHead(
loaderTree,
{},
[]
)
const [resolvedHead, metadataItems] = await resolveHead({
tree: loaderTree,
parentParams: {},
metadataItems: [],
})
// Flight data that is going to be passed to the browser.
// Currently a single item array but in the future multiple patches might be combined in a single request.
const flightData: FlightData = [
Expand Down Expand Up @@ -1074,7 +1093,11 @@ export async function renderToHTMLOrFlight(
}
: {}

const [initialHead, metadataItems] = await resolveHead(loaderTree, {}, [])
const [initialHead, metadataItems] = await resolveHead({
tree: loaderTree,
parentParams: {},
metadataItems: [],
})

/**
* A new React Component that renders the provided React Component
Expand Down
14 changes: 13 additions & 1 deletion packages/next/src/server/lib/app-dir-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,17 @@ export async function getLayoutOrPageModule(loaderTree: LoaderTree) {
const { layout, page } = loaderTree[2]
const isLayout = typeof layout !== 'undefined'
const isPage = typeof page !== 'undefined'
return isLayout ? await layout[0]() : isPage ? await page[0]() : undefined

let value = undefined
let modType: 'layout' | 'page' | undefined = undefined
if (isLayout) {
value = await layout[0]()
modType = 'layout'
}
if (isPage) {
value = await page[0]()
modType = 'page'
}

return [value, modType] as const
}
1 change: 1 addition & 0 deletions packages/next/src/shared/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export const TEMPORARY_REDIRECT_STATUS = 307
export const PERMANENT_REDIRECT_STATUS = 308
export const STATIC_PROPS_ID = '__N_SSG'
export const SERVER_PROPS_ID = '__N_SSP'
export const PAGE_SEGMENT_KEY = '__PAGE__'
export const GOOGLE_FONT_PROVIDER = 'https://fonts.googleapis.com/'
export const OPTIMIZED_FONT_PROVIDERS = [
{ url: GOOGLE_FONT_PROVIDER, preconnect: 'https://fonts.gstatic.com' },
Expand Down
8 changes: 4 additions & 4 deletions test/e2e/opentelemetry/opentelemetry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,23 +130,23 @@ createNextDescribe(
},
Object {
"attributes": Object {
"next.span_name": "generateMetadata",
"next.span_name": "generateMetadata /app/layout",
"next.span_type": "ResolveMetadata.generateMetadata",
},
"kind": 0,
"name": "generateMetadata",
"name": "generateMetadata /app/layout",
"parentId": "[parent-id]",
"status": Object {
"code": 0,
},
},
Object {
"attributes": Object {
"next.span_name": "generateMetadata",
"next.span_name": "generateMetadata /app/rsc-fetch/page",
"next.span_type": "ResolveMetadata.generateMetadata",
},
"kind": 0,
"name": "generateMetadata",
"name": "generateMetadata /app/rsc-fetch/page",
"parentId": "[parent-id]",
"status": Object {
"code": 0,
Expand Down

0 comments on commit 10e35db

Please sign in to comment.