Skip to content

Commit

Permalink
[metadata] Merge the metadata resolve apis into one api (vercel#74191)
Browse files Browse the repository at this point in the history
  • Loading branch information
huozhi authored Dec 23, 2024
1 parent 75a9dfa commit 7a47ed5
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 48 deletions.
103 changes: 59 additions & 44 deletions packages/next/src/lib/metadata/metadata.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@ import {
} from './generate/opengraph'
import { IconsMetadata } from './generate/icons'
import {
resolveMetadataItems,
accumulateMetadata,
accumulateViewport,
type MetadataErrorType,
resolveMetadata,
resolveViewport,
} from './resolve-metadata'
import { MetaFilter } from './generate/meta'
import type {
Expand Down Expand Up @@ -196,24 +195,14 @@ async function getResolvedMetadataImpl(
errorType?: MetadataErrorType | 'redirect'
): Promise<React.ReactNode> {
const errorConvention = errorType === 'redirect' ? undefined : errorType

const metadataItems = await resolveMetadataItems(
return renderMetadata(
tree,
searchParams,
errorConvention,
getDynamicParamFromSegment,
metadataContext,
createServerParamsForMetadata,
workStore
)
const elements: Array<React.ReactNode> = createMetadataElements(
await accumulateMetadata(metadataItems, metadataContext)
)
return (
<>
{elements.map((el, index) => {
return cloneElement(el as React.ReactElement, { key: index })
})}
</>
workStore,
errorConvention
)
}

Expand All @@ -227,24 +216,14 @@ async function getNotFoundMetadataImpl(
workStore: WorkStore
): Promise<React.ReactNode> {
const notFoundErrorConvention = 'not-found'
const notFoundMetadataItems = await resolveMetadataItems(
return renderMetadata(
tree,
searchParams,
notFoundErrorConvention,
getDynamicParamFromSegment,
metadataContext,
createServerParamsForMetadata,
workStore
)

const elements: Array<React.ReactNode> = createMetadataElements(
await accumulateMetadata(notFoundMetadataItems, metadataContext)
)
return (
<>
{elements.map((el, index) => {
return cloneElement(el as React.ReactElement, { key: index })
})}
</>
workStore,
notFoundErrorConvention
)
}

Expand All @@ -258,18 +237,55 @@ async function getResolvedViewportImpl(
errorType?: MetadataErrorType | 'redirect'
): Promise<React.ReactNode> {
const errorConvention = errorType === 'redirect' ? undefined : errorType
return renderViewport(
tree,
searchParams,
getDynamicParamFromSegment,
createServerParamsForMetadata,
workStore,
errorConvention
)
}

const metadataItems = await resolveMetadataItems(
const getNotFoundViewport = cache(getNotFoundViewportImpl)
async function getNotFoundViewportImpl(
tree: LoaderTree,
searchParams: Promise<ParsedUrlQuery>,
getDynamicParamFromSegment: GetDynamicParamFromSegment,
createServerParamsForMetadata: CreateServerParamsForMetadata,
workStore: WorkStore
): Promise<React.ReactNode> {
const notFoundErrorConvention = 'not-found'
return renderViewport(
tree,
searchParams,
errorConvention,
getDynamicParamFromSegment,
createServerParamsForMetadata,
workStore
workStore,
notFoundErrorConvention
)
const elements: Array<React.ReactNode> = createViewportElements(
await accumulateViewport(metadataItems)
}

async function renderMetadata(
tree: LoaderTree,
searchParams: Promise<ParsedUrlQuery>,
getDynamicParamFromSegment: GetDynamicParamFromSegment,
metadataContext: MetadataContext,
createServerParamsForMetadata: CreateServerParamsForMetadata,
workStore: WorkStore,
errorConvention?: MetadataErrorType
) {
const resolvedMetadata = await resolveMetadata(
tree,
searchParams,
errorConvention,
getDynamicParamFromSegment,
createServerParamsForMetadata,
workStore,
metadataContext
)
const elements: Array<React.ReactNode> =
createMetadataElements(resolvedMetadata)
return (
<>
{elements.map((el, index) => {
Expand All @@ -279,26 +295,25 @@ async function getResolvedViewportImpl(
)
}

const getNotFoundViewport = cache(getNotFoundViewportImpl)
async function getNotFoundViewportImpl(
async function renderViewport(
tree: LoaderTree,
searchParams: Promise<ParsedUrlQuery>,
getDynamicParamFromSegment: GetDynamicParamFromSegment,
createServerParamsForMetadata: CreateServerParamsForMetadata,
workStore: WorkStore
): Promise<React.ReactNode> {
const notFoundErrorConvention = 'not-found'
const notFoundMetadataItems = await resolveMetadataItems(
workStore: WorkStore,
errorConvention?: MetadataErrorType
) {
const notFoundResolvedViewport = await resolveViewport(
tree,
searchParams,
notFoundErrorConvention,
errorConvention,
getDynamicParamFromSegment,
createServerParamsForMetadata,
workStore
)

const elements: Array<React.ReactNode> = createViewportElements(
await accumulateViewport(notFoundMetadataItems)
notFoundResolvedViewport
)
return (
<>
Expand Down
47 changes: 43 additions & 4 deletions packages/next/src/lib/metadata/resolve-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,7 @@ async function collectMetadata({
}
}

const cachedResolveMetadataItems = cache(resolveMetadataItems)
export { cachedResolveMetadataItems as resolveMetadataItems }
async function resolveMetadataItems(
const resolveMetadataItems = cache(async function (
tree: LoaderTree,
searchParams: Promise<ParsedUrlQuery>,
errorConvention: MetadataErrorType | undefined,
Expand All @@ -496,7 +494,7 @@ async function resolveMetadataItems(
createServerParamsForMetadata,
workStore
)
}
})

async function resolveMetadataItemsImpl(
metadataItems: MetadataItems,
Expand Down Expand Up @@ -901,3 +899,44 @@ export async function accumulateViewport(
}
return resolvedViewport
}

// Exposed API for metadata component, that directly resolve the loader tree and related context as resolved metadata.
export async function resolveMetadata(
tree: LoaderTree,
searchParams: Promise<ParsedUrlQuery>,
errorConvention: MetadataErrorType | undefined,
getDynamicParamFromSegment: GetDynamicParamFromSegment,
createServerParamsForMetadata: CreateServerParamsForMetadata,
workStore: WorkStore,
metadataContext: MetadataContext
): Promise<ResolvedMetadata> {
const metadataItems = await resolveMetadataItems(
tree,
searchParams,
errorConvention,
getDynamicParamFromSegment,
createServerParamsForMetadata,
workStore
)
return accumulateMetadata(metadataItems, metadataContext)
}

// Exposed API for viewport component, that directly resolve the loader tree and related context as resolved viewport.
export async function resolveViewport(
tree: LoaderTree,
searchParams: Promise<ParsedUrlQuery>,
errorConvention: MetadataErrorType | undefined,
getDynamicParamFromSegment: GetDynamicParamFromSegment,
createServerParamsForMetadata: CreateServerParamsForMetadata,
workStore: WorkStore
): Promise<ResolvedViewport> {
const metadataItems = await resolveMetadataItems(
tree,
searchParams,
errorConvention,
getDynamicParamFromSegment,
createServerParamsForMetadata,
workStore
)
return accumulateViewport(metadataItems)
}

0 comments on commit 7a47ed5

Please sign in to comment.