Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/basic-features/data-fetching.md
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,7 @@ The `context` parameter is an object containing the following keys:

`getServerSideProps` should return an object with:

- `props` - An **optional** object with the props that will be received by the page component. It should be a [serializable object](https://en.wikipedia.org/wiki/Serialization)
- `props` - An **optional** object with the props that will be received by the page component. It should be a [serializable object](https://en.wikipedia.org/wiki/Serialization) or a Promise that resolves to a serializable object.
- `notFound` - An **optional** boolean value to allow the page to return a 404 status and page. Below is an example of how it works:

```js
Expand Down
4 changes: 4 additions & 0 deletions packages/next/server/render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,10 @@ export async function renderToHTML(
;(renderOpts as any).isRedirect = true
}

if ((data as any).props instanceof Promise) {
;(data as any).props = await (data as any).props
}

if (
(dev || isBuildTimeSSG) &&
!isSerializableProps(
Expand Down
15 changes: 15 additions & 0 deletions test/integration/getserversideprops/pages/promise/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export async function getServerSideProps() {
return {
props: (async function () {
return {
text: 'promise',
}
})(),
}
}

export default ({ text }) => (
<>
<div>hello {text}</div>
</>
)
11 changes: 11 additions & 0 deletions test/integration/getserversideprops/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ const expectedManifestRoutes = () => [
slug: 'slug',
},
},
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/promise.json$`
),
page: '/promise',
},
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/refresh.json$`
Expand Down Expand Up @@ -523,6 +529,11 @@ const runTests = (dev = false) => {
expect(data.pageProps.post).toBe('post-1')
})

it('should return data correctly when props is a promise', async () => {
const html = await renderViaHTTP(appPort, `/promise`)
expect(html).toMatch(/hello.*?promise/)
})

it('should navigate to a normal page and back', async () => {
const browser = await webdriver(appPort, '/')
let text = await browser.elementByCss('p').text()
Expand Down