There is no reason that using graphQL with apollo should prevent us from having static rendered pages
A clear and concise description of what you want and what your use case is.
Because with-Apollo uses getInitialProps in the HOC withApollo, even if there is no calls to graphQL that need to be resolved on the server render, a non-static page is generated.
I'd like to see with-Apollo modified so that if all the graphQL is rendered on the client, a static page can be rendered. That is, not requiring getInitialProps
@HaNdTriX added a ssr: false option to the withApollo hoc. https://github.com/zeit/next.js/blob/canary/examples/with-apollo/lib/apollo.js#L19
I have added the same api to the with-redux example. See the following comment to check out how it works.
https://github.com/zeit/next.js/issues/9285#issuecomment-549039028
- export default withApollo(IndexPage)
+ export default withApollo(IndexPage, {
+ ssr: false
+ })
https://github.com/zeit/next.js/blob/canary/examples/with-apollo/pages/index.js#L29
@timneutkens I thought the rule was that if getInitialProps was mentioned inside of the /pages/mypage.js file that it would not statically generate. I did just test the example and you are correct in saying that it does statically render with that flag set.
@pkellner it checks the method on the function/class being exported, so it's aware of runtime assignment.
@HaNdTriX it's probably a good idea to document this option.
Oh I just saw that I already documented the most important use cases in here.
I will try to add more docs in the future. As a sneak peek have a look at this:
The HOC withApollo supports multiple render strategies:
export default withApollo(PageComponent)
This strategy automatically determines your data requirements on the server using apollos getDataFromTree. Apollo may need to render your app multiple times in order to execute each query. After all queries have been resolved Next.js takes over and renders your app with the state generated from apollo.
export default withApollo(PageComponent, {
ssr: false
})
This strategy allows you to use Next.js automatic static optimisation feature. The server will render the markup statically without any data. In this case apollo will fetch its data on the client only.
PageComponent.getInitialProps = async (ctx) => {
await ctx.apolloClient.query({
query: gql`
query allPosts($first: Int!, $skip: Int!) {
allPosts(orderBy: createdAt_DESC, first: $first, skip: $skip) {
id
title
votes
url
createdAt
}
_allPostsMeta {
count
}
}
`,
variables: {
skip: 0,
first: 10,
}
})
return {}
}
export default withApollo(PageComponent, {
ssr: false
})
This strategy doesn't run apollos getDataFromTree. Instead you can explicitly determine what should be fetched on the server. We only recommend this strategy if you really need to optimize your ssr time.
This will probably also help: https://github.com/zeit/next.js/issues/9524
Thanks @timneutkens You've done a great job of articulating where I see issues need to be addressed in how SSR and SSG need to work on a single site. I struggle with how to bring it all together with the two big sticking points for me being authentication and routing in serverless environments. I feel like there is a lot of stuff I don't understand, and when I talk to others smarter then me, they too don't (or can't) articulate how this is all going to come together.
I'm optimistic that you will figure it out and bring it to the masses (me), so we can all consume it and get the bests of SSR and SSG in our apps and not have a heavy express-ssr piece bundled into our SSR end point.
Closing this issue because your https://github.com/zeit/next.js/issues/9524 is the better discussion.
@HaNdTriX , I know this is a JavaScript/Redux thing, but still hoping for some help.
I want to use compose with withApollo so I can export withApollo and withRedux. I can't figure out how to pass the ssr parameter when using compose. I tried something like this but it did not work.
const withApollo1 = () => withApollo(Page, { ssr: true });
export default compose(
withApollo1,
withRedux
)(Page);
@HaNdTriX I think you forgot Page in the arguments:
const withApollo1 = (Page) => withApollo(Page, { ssr: true });
Oh I just saw that I already documented the most important use cases in here.
I will try to add more docs in the future. As a sneak peek have a look at this:
Render strategies
The HOC
withApollosupports multiple render strategies:
- [x] 1. automatic server side fetch
- [x] 2. no server side fetch
- [ ] 3. manual server side fetch
1. automatic server side fetch (default)
export default withApollo(PageComponent)This strategy automatically determines your data requirements on the server using apollos
getDataFromTree. Apollo may need to render your app multiple times in order to execute each query. After all queries have been resolved Next.js takes over and renders your app with the state generated from apollo.2. no server side fetch
export default withApollo(PageComponent, { ssr: false })This strategy allows you to use Next.js automatic static optimisation feature. The server will render the markup statically without any data. In this case apollo will fetch its data on the client only.
3. manual server side fetch
PageComponent.getInitialProps = async (ctx) => { await ctx.apolloClient.query({ query: gql` query allPosts($first: Int!, $skip: Int!) { allPosts(orderBy: createdAt_DESC, first: $first, skip: $skip) { id title votes url createdAt } _allPostsMeta { count } } `, variables: { skip: 0, first: 10, } }) return {} } export default withApollo(PageComponent, { ssr: false })This strategy doesn't run apollos
getDataFromTree. Instead you can explicitly determine what should be fetched on the server. We only recommend this strategy if you really need to optimize your ssr time.
I was looking for the 3rd option precisely
Thanks a lot man.
Most helpful comment
Oh I just saw that I already documented the most important use cases in here.
I will try to add more docs in the future. As a sneak peek have a look at this:
Render strategies
The HOC
withApollosupports multiple render strategies:1. automatic server side fetch (default)
This strategy automatically determines your data requirements on the server using apollos
getDataFromTree. Apollo may need to render your app multiple times in order to execute each query. After all queries have been resolved Next.js takes over and renders your app with the state generated from apollo.2. no server side fetch
This strategy allows you to use Next.js automatic static optimisation feature. The server will render the markup statically without any data. In this case apollo will fetch its data on the client only.
3. manual server side fetch
This strategy doesn't run apollos
getDataFromTree. Instead you can explicitly determine what should be fetched on the server. We only recommend this strategy if you really need to optimize your ssr time.