Next.js: [Next 9.0.0] req/res are undefined in getInitialProps in _document.js

Created on 8 Jul 2019  路  11Comments  路  Source: vercel/next.js

Bug report

Describe the bug

After having upgraded to v9 this morning we noticed that CSP was failing. Upon further investigation, it turned out that ctx.req and ctx.res were returning undefined in _document.js (or .ts) when calling getInitialProps.

This has been reproduced by combining the basic custom-document example as well as the custom-server example.

To Reproduce

https://codesandbox.io/s/next9-getinitialprops-bug-f1lj7

Expected behavior

req and res should have content.

Screenshots

Server logs:
image

System information

  • OS: MacOS / Linux (codesandbox + node:10-alpine tested)
  • server-side issue
  • Version of Next.js: 9.0.0
documentation

Most helpful comment

@exogen it should not. getInitialProps in _document is also the rendering pipeline so everyone needs to have in their _document. It would deopt pretty much every Next.js application in existence as most css-in-js solutions need access to this specifically.

In case you want to opt-out for the whole application you can add _app.js with a getInitialProps method.

All 11 comments

Hey @frankrobert-ls! This is because the page is being statically prerendered -- we should improve the documentation around this. 馃槃

We'll double check this is working as expected, too.

@Timer Thanks for responding so quickly! If this is working as intended (as I understood from your response), is there a proposed workaround or alternative solution to getting access to server-side properties?

@frankrobert-ls since the page is statically prerendered _document "middleware" (i.e. getInitialProps) will not run when deployed to production -- that's why req and res is undefined in this case (to emulate prod during dev).

The _document will only be used for its custom rendering function.

If you'd like to force the page to server-side render (so you can use GIP/middleware), you'll need to add a stub getInitialProps to your page -- this causes Next.js to de-optimize (disable) this performance feature.

It seems like a custom _document getInitialProps should disable the feature just like _app's does.

@exogen it should not. getInitialProps in _document is also the rendering pipeline so everyone needs to have in their _document. It would deopt pretty much every Next.js application in existence as most css-in-js solutions need access to this specifically.

In case you want to opt-out for the whole application you can add _app.js with a getInitialProps method.

True, I think the surprising part is that the default assumption is the unsafe backwards-incompatible one (assume they aren't using req/res in their Document.getInitialProps) vs. the safe backwards compatible one (assume they could be using those and provide a way to opt into prerender).

@exogen this is why it was released behind a major version, i.e. 9.0.0.
We made the decision to be fast by default instead of relying on the user to remember to prerender a page.

Adding a check to see if req or res is undefined seems like a small price to pay for massive performance gains. 馃槃

@Timer I am facing the same problem. I got this

since the page is statically prerendered _document "middleware" (i.e. getInitialProps) will not run when deployed to production -- that's why req and res is undefined in this case (to emulate prod during dev).

I would like to know what should I do to make _document.js to force server side render and how? I'm new to nextjs.

I am facing the same problem too. is there any workaround?

This would be particularly helpful for setting the lang on the <Html> tag. I'd like to see in the request what domain name is being used (.com, .nl, .pt, etc.) and determine the appropriate fallback language from that. :)

@rahadkc @derakhshanfar

The documentation added by that commit above is reflected here:

https://nextjs.org/docs/advanced-features/automatic-static-optimization#caveats

In practice, req/res will be undefined in your _Document as long as the app is being statically rendered, which is the default behaviour when your application omits getInitialProps in any of your pages.

A way around this is to add a getInitialProps call to your _App, and static rendering will no longer block the req/res response in _Document. The downside of this method means that you'll be forgoing static rendering on -any- pages, so as a happy medium I just getInitialProps on the pages I need to SSR and let static rendering handle the rest.

Was this page helpful?
0 / 5 - 0 ratings