Skip to content

Commit

Permalink
Allow generateMetadata to be synchronous (#45696)
Browse files Browse the repository at this point in the history
The very-newly-released `generateMetadata` function currently does not
allow itself to be synchronous. It leads to situations like this

```ts
export async function generateMetadata() {
  return { title: "Hello, world!" };
}
```

where there's evidently no reason to use `async`, but it's forced by
Next.js.

This PR aims to remove this restriction: `generateMetadata` can be
synchronous now.

## Bug

- [x] Related issues linked using `fixes #45685`
- [ ] Integration tests added
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the
feature request has been accepted for implementation before opening a
PR.
- [ ] Related issues linked using `fixes #number`
- [x]
[e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm build && pnpm lint`
- [ ] The "examples guidelines" are followed from [our contributing
doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)

Signed-off-by: Vu Van Dung <me@joulev.dev>
Co-authored-by: Jiachi Liu <inbox@huozhi.im>
  • Loading branch information
joulev and huozhi authored Feb 8, 2023
1 parent a25c32a commit 7654d7b
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ interface IEntry {
: ''
}
metadata?: any
generateMetadata?: (props: PageProps, parent: ResolvingMetadata) => Promise<any>
generateMetadata?: (props: PageProps, parent: ResolvingMetadata) => any | Promise<any>
}
// =============
Expand Down
9 changes: 6 additions & 3 deletions packages/next/src/lib/metadata/resolve-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,9 @@ function merge(
}
}

type MetadataResolver = (_parent: ResolvingMetadata) => Promise<Metadata>
type MetadataResolver = (
_parent: ResolvingMetadata
) => Metadata | Promise<Metadata>
export type MetadataItems = [
Metadata | MetadataResolver | null,
Metadata | null
Expand Down Expand Up @@ -410,10 +412,11 @@ export async function accumulateMetadata(

for (const item of metadataItems) {
const [metadataExport, staticFilesMetadata] = item
const layerMetadataPromise =
const layerMetadataPromise = Promise.resolve(
typeof metadataExport === 'function'
? metadataExport(parentPromise)
: Promise.resolve(metadataExport)
: metadataExport
)

parentPromise = parentPromise.then((resolved) => {
return layerMetadataPromise.then((exportedMetadata) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default function Page() {
return 'synchronous generateMetadata'
}

export function generateMetadata() {
return {
title: 'synchronous generateMetadata',
}
}
5 changes: 5 additions & 0 deletions test/e2e/app-dir/metadata/metadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,11 @@ createNextDescribe(
/params - blog query - xxx/
)
})

it('should support synchronous generateMetadata export', async () => {
const browser = await next.browser('/basic/sync-generate-metadata')
expect(await getTitle(browser)).toBe('synchronous generateMetadata')
})
})

describe('opengraph', () => {
Expand Down

0 comments on commit 7654d7b

Please sign in to comment.