Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

with-Apollo example makes it impossible to generate static pages #9503

Closed
pkellner opened this issue Nov 23, 2019 · 8 comments

Comments

@pkellner
Copy link
Contributor

@pkellner pkellner commented Nov 23, 2019

Feature request

Is your feature request related to a problem? Please describe.

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.

Describe the solution you'd like

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

@timneutkens

This comment has been minimized.

Copy link
Member

@timneutkens timneutkens commented Nov 24, 2019

@HaNdTriX

This comment has been minimized.

Copy link
Contributor

@HaNdTriX HaNdTriX commented Nov 24, 2019

I have added the same api to the with-redux example. See the following comment to check out how it works.

#9285 (comment)

- 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

@pkellner

This comment has been minimized.

Copy link
Contributor Author

@pkellner pkellner commented Nov 24, 2019

@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.

@timneutkens

This comment has been minimized.

Copy link
Member

@timneutkens timneutkens commented Nov 24, 2019

@pkellner it checks the method on the function/class being exported, so it's aware of runtime assignment.

@timneutkens

This comment has been minimized.

Copy link
Member

@timneutkens timneutkens commented Nov 24, 2019

@HaNdTriX it's probably a good idea to document this option.

@HaNdTriX

This comment has been minimized.

Copy link
Contributor

@HaNdTriX HaNdTriX commented Nov 25, 2019

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 withApollo supports multiple render strategies:

  • 1. automatic server side fetch
  • 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.

@timneutkens

This comment has been minimized.

Copy link
Member

@timneutkens timneutkens commented Nov 26, 2019

This will probably also help: #9524

@pkellner

This comment has been minimized.

Copy link
Contributor Author

@pkellner pkellner commented Nov 26, 2019

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 #9524 is the better discussion.

@pkellner pkellner closed this Nov 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.