[Docs] Change Dynamic Routing Example to Avoid SPR Footgun
See original GitHub issueFeature request
First of all, thanks for all of your hard work on Next.js! There’s so much amazing technology in this framework, and it really feels like standing on the shoulders of giants using it. Keep it up! 🚀
Is your feature request related to a problem? Please describe.
If you use the useRouter
Dynamic Routing example below from the current docs, it will out of the box apply the Serverless Prerendering (SPR) optimization and parameters will for a short time be undefined
(let’s call this Flash of Missing Content).
import { useRouter } from 'next/router'
const Post = () => {
const router = useRouter()
const { pid } = router.query
return <p>Post: {pid}</p>
}
export default Post
This is explained much further down in a box that can be easily missed:
Note: Pages that are statically optimized by automatic prerendering will be hydrated without their route parameters provided (query will be empty, i.e. {}). After hydration, Next.js will trigger an update to your application to provide the route parameters in the query object. If your application cannot tolerate this behavior, you can opt-out of static optimization by capturing the query parameter in getInitialProps.
The Flash of Missing Content is annoying and it is unclear why it’s happening to a user not versed in all of the new features of Next.js.
In addition, this can be a problem in a simple case of trying to access a property on an object found using the query parameter (“Cannot read property ‘name’ of undefined”):
import { useRouter } from 'next/router'
import posts from '../posts'
const Post = () => {
const router = useRouter()
const { pid } = router.query
const post = posts.find(p => p.id === pid)
return (
<p>
Post: {post.name} {/* 💥 Error! */}
</p>
)
}
export default Post
Describe the solution you’d like
The example should work out of the box (copy + paste) without the flash of missing content, by at least recommending the use of the getInitialProps
method.
Post.getInitialProps = async () => {
return {};
};
Describe alternatives you’ve considered
An alternative (which would actually be preferable, because it’s zero-config) would be for the useRouter
hook to add an empty getInitialProps
method automatically when its used (of course, only if it’s not defined by the user). This would be the least footgun-y and offer the most pleasant DX.
A second alternative would be to have the getInitialProps
part be in a separate box directly after the example, with some explainer text above it.
Another alternative would be to have the code in the example but commented out. This would probably lead to less usage of the code though, and would be much less desirable.
Additional context
By googling for the issue (“Next.js useRouter parameters undefined” or “Next.js useRouter server-side rendering”), you can find this issue, which provides the example that inspired this issue:
Issue Analytics
- State:
- Created 4 years ago
- Reactions:16
- Comments:11 (9 by maintainers)
The more I think about it, the more that I actually prefer my first alternative I mentioned above - the zero-configuration option of the
useRouter
hook automatically configuring the component to have an emptygetInitialProps
if one doesn’t exist…@timneutkens what is the recommended approach to solving this issue now that #9524 has been merged?