Intended outcome:
When following the next.js
with-apollo
example using @apollo/client-beta.8
or any newer client in ssrMode
, we should see the loaded GraphQL data in our markup when we view the page source.
Actual outcome:
When we inspect the page source, the markup shows that our page is in a loading state.
How to reproduce the issue:
Use beta.8
or greater in the next.js
with-apollo
example. The last two commits in the repo included below will show the viewed source of a page including markup in a loading state when using beta.8, and returning the expected markup with GraphQL supplied data in beta.7.
https://github.com/lyonsv/with-apollo-app
A quick sample of a few versions before 7 suggest this is a regression in introduced between 7 and 8. Glancing at the commits between the two versions, there's a lot going on and there's nothing obvious to me that could be the cause.
The commits where the the problem occurs should be identifiable below:
https://github.com/apollographql/apollo-client/commits/ab0bbe2f5b06465c9c54de8c633e119e21881504
The problem was raised by tests that I have written in Cypress inspecting the request, and on my express server used in Next.js. Happy to contribute similar tests to prevent this regression from occurring again - it's a hard one to spot.
Versions
System:
OS: macOS 10.15.5
Binaries:
Node: 14.2.0 - /usr/local/bin/node
Yarn: 1.7.0 - ~/.yarn/bin/yarn
npm: 6.14.4 - /usr/local/bin/npm
Browsers:
Chrome: 83.0.4103.97
Firefox: 65.0
Safari: 13.1.1
npmPackages:
@apollo/client: 3.0.0-beta.8 => 3.0.0-beta.8
@lyonsv which version of @apollo/react-ssr
are you running? I was using 3.1.5
and I had my data missing too.
When I bumped it to 4.0.0-beta.1
it fixed my problem.
@capaj the problem seems to be independent of @apollo/react-ssr
. This issue was created to focus on the SSR problem that's replicable in https://github.com/lyonsv/with-apollo-app by moving from the most recent commit (broken) to the previous commit (working). These two commits show that @apollo/client-beta.8
and greater will return markup in a loading state in the with-apollo
next.js example, and every release from beta.7
backwards returns markup containing the loaded data.
In my actual production project I was using the 4.0.0-beta.1
of @apollo/react-ssr
and SSR was still broken when used with '@apollo/client' 3, but I think the example repo that I've created better explains the problem...because I've all sorts of things going on in my production project that I think obfuscate the issue.
I could also reproduce it with "@apollo/client": "3.0.0-rc.3",
and -rc.4
Any combination of versions that works? I'm missing server-side rendering for a long time now, as it's not working for me since ~v2.
Similar issue: https://github.com/apollographql/react-apollo/issues/3678
In my example SSR works for beta 7 and below. I would imagine a lot of other things do not work in a release that far back.
Curiously, in the issue you鈥檝e linked to, it鈥檚 describing a problem for a version before beta 7, but maybe it鈥檚 not the same problem.
I鈥檇 suggest rolling back to v2 of Apollo client to get everything working if you need SSR immediately. There might be some work in rolling back as @Apollo/client v3 replaces a few packages, but rolling forward again once this issue is resolved should be straightforward.
Thanks, I tried beta 7 again and fixed some dependencies and SSR worked. On a side note, looks like Next.js won't support getDataFromTree
anymore...
@renato my example is using the updated with-Apollo example that the Next.js team merged several days ago. It鈥檚 dramatically simpler, and doesn鈥檛 use getDataFromTree. I鈥檝e yet to try and update the code in my production app to make use of SSG, but you鈥檙e correct that some changes will need to be made - it鈥檚 looking like those changes will involve a lot of code deletion, which would be be nice.
I鈥檇 recommend rolling everything back to Apollo Client 2 for the moment, and not to use beta.7. The git commits between that release and the current RC suggest lots of bugs have been found and fixed over the last few months.
I think using apollo with nextjs was a wrong decision altogether :(
@jsartisan my experience has been that both are magic technologies when applied to suitable problems. The current with-Apollo example from next.js shows a pretty simple example of how to get them to work together with Apollo client 2
Switched back to apollo-boost for SSR.
@jsartisan can you elaborate little more on how switching to apollo-boost worked? iam using next.js and struggling to get SSR working with apollo , what versions of apollo-client and next.js are you using? are you following the new example or getDataFromTree?
@msreekm Unfortunately the current next.js apollo example got a lobotomy and isn't practical to refer to for how bigger companies are currently using next with apollo and ssr.
I think this example is probably a good starting point for anyone wanting to get started with next and apollo:
https://github.com/vercel/next.js/discussions/11957#discussioncomment-27012
Hi @lyonsv! I pulled down the reproduction and tested it with the lasted release 3.0.0-rc.8
and it appears to resolve the issue. Could you double-check that it does?
Hi @nodabladam ,Thanks for the link. i will give it a try.
just worried that if we still get Apptree working now , timneutkens mentioned in the same thread that it may break in near future ? do you still recommend this approach?
https://github.com/vercel/next.js/discussions/11957#discussioncomment-29427
@jcreighton I'm still seeing "Loading" in the page source, and not the markup that should should have been generated.
The steps I've followed to reproduce are:
@apollo/client
from 3.0.0-beta.8
to 3.0.0-rc.8
npm i
This produces the markup pasted below. Did you see markup returned from the server that included the loaded graphql data? Maybe I need to dig around a bit more - and clear a few other things that could be cached.
@lyonsv The difference between beta.7
and beta.8
is the PostList
component is receiving its data vs not (the query succeeding in index.js
in both versions). That issue is resolved as of beta.23
. What you're encountering now is related to loading being set to true
on the server, see https://github.com/apollographql/react-apollo/issues/3338#issuecomment-528462945 and https://github.com/apollographql/react-apollo/issues/3338#issuecomment-571854056. On this line, you'll want to check if !data
in addition to the loading states. Then you'll see the markup as expected.
That makes sense, thanks @jcreighton . A check for !data
solves the problem using the latest release candidate.
@lyonsv Thanks for the quick reply to @jcreighton's questions! Glad this is resolved for you.
@msreekm @nodabladam @jsartisan Mind taking your discussion somewhere else?
@benjamn Sorry benjamn for the noise. The latest next apollo example makes SSR stop working in certain cases for existing apps and I linked to a thread about that to prevent people from saying this still isn't working for the wrong reasons but I should have been alot more clear about that in my post.
So checking for!data
before the loading check solves the issue for us as well, but it's a bit disturbing that the semantics of "loading" have changed. I suspect this is going to cause a lot of headache for people migrating to 3.x.
Although this issue is resolved, I seem to have used some keywords that will lead people here for reasons that are more to do with the next.js examples, than with apollo client. Summary of my knowledge below:
if (!data && loading) { return <Loading />}
, before returning your component that uses loaded data. Any Apollo/client version greater than beta.23
should be fine.Point 3 is going to catch a lot of people, as you won't spot that SSR is broken in the browser or in your test suite, unless you test the body of the response to a request - which I'd recommend doing. I had the inelegant cypress test below in my code base, and it did the job:
describe('a ssr request visits homepage', () => {
it('sees the hero section of the app', () => {
cy.request(routes.home).as('homepage')
cy.get('@homepage').should(response => {
// home-content-desktop should be visible in loaded state
const ssrHero = response.body.search('home-content-desktop')
// if it was not visible, a search for the string position within body would return -1.
expect(ssrHero).to.not.eq(-1)
})
})
})
Most helpful comment
Although this issue is resolved, I seem to have used some keywords that will lead people here for reasons that are more to do with the next.js examples, than with apollo client. Summary of my knowledge below:
if (!data && loading) { return <Loading />}
, before returning your component that uses loaded data. Any Apollo/client version greater thanbeta.23
should be fine.Point 3 is going to catch a lot of people, as you won't spot that SSR is broken in the browser or in your test suite, unless you test the body of the response to a request - which I'd recommend doing. I had the inelegant cypress test below in my code base, and it did the job: