-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Next JS 13 (AppDir and RSC) with ApolloClient #10344
Comments
Hi @lloydrichards, thanks for posting this Issue! The team is really interested in RSC and, as you note, there are some changes that will need to be made in order to make Apollo Client and Next.js 13 work together out of the box. We're working on supporting React 18 features like Suspense and |
glad to hear things will be moving in the future, and will just have to wait on using ApolloClient for the time being. I did some experimenting and managed to get things working first with https://github.com/lloydrichards/reproduced-fetch-error but most of the credit for getting working goes to https://github.com/graphqlwtf I'll keep my eyes open for any future development in ApolloClient and wish you luck! |
@lloydrichards thanks for letting us know about the challenges here. You can follow along with some upcoming Alpha releases we have planned to better support React 18 Suspense and SSR (see our Roadmap for more details) Hopefully once this is better supported you can give Apollo Client a try again. |
hey all, I'm using NextJs 13.0.6, and Apollo Client 3.7.2. The issue could be specific to using a credentials (email/password) provider with Nextauth.js, but it seems like whenever I try to perform an apollo query on the server side, I get an error. "[Network error]: TypeError: fetch failed". The same code seems work fine on the client side. Any chance y'all have a guess as whether this is a bug/incompability between these libraries or if I'm doing something wrong? Not sure if the nextjs override for fetch() could be the cause of this issue If it's any help, I am mostly following https://github.com/shadcn/taxonomy which is the only solid Nextjs 13 example I'm found. |
Maybe I'm doing something wrong, but seems like this fixed my issue #10310 (comment) |
I'm curious if there's any information yet about what the recommended interface will look like for using Apollo with Next 13. For example, this blog post for Next 12 talks about using the old I realize this is all very new and I probably should not be using the /app dir yet if I want to use Apollo, but some thoughts on this would be appreciated since as far as I can tell there's no real documentation on this yet. |
I did get it working with Apollo client but it invoked doing some weird
things with wrapping the layout.tsx in a provider.tsx that lead flagged
with "use client" and then whenever Apollo queries were called also using
the same flag. This really missed the point of using the app dir for me so
I ended up using `grapwhl-request` instead of Apollo client and everything
works using just the app dir and RSC
…On Tue, 20 Dec 2022, 19:17 Michiel Sikma, ***@***.***> wrote:
I'm curious if there's any information yet about what the recommended
interface will look like for using Apollo with Next 13.
For example, this blog post
<https://www.apollographql.com/blog/apollo-client/next-js/next-js-getting-started/>
for Next 12 talks about using the old getStaticProps() and
getServerSideProps() api that is not supported in the /app dir.
I realize this is all very new and I probably should not be using the /app
dir yet if I want to use Apollo, but some thoughts on this would be
appreciated since as far as I can tell there's no real documentation on
this yet.
—
Reply to this email directly, view it on GitHub
<#10344 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AOHWIQKON2NDZXGBHC2QTJTWOHZ45ANCNFSM6AAAAAASZL4AY4>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Hi all , has anyone been able to use NextJS 13 and Apollo Client yet? I'm starting a new project and really want to do it on NextJS 13, but I need tools to work with GraphQL. |
you can still use Apollo Client, but you'll end up with everything in the
app directory being a client component. If that's okay with you then all
you need to do is wrap children in the layout.tsx in the ApolloProvider,
the same way you would in _app.tsx. I think with the new Typescript plug
it it should automatically detect that everything is a client component so
you don't need to use `use client` but you'll have to avoid any of the
getServerSideProps patterns that you would use in Pages.
Or just use Next 13, but in the pages dir. that all still works fine
…On Thu, Jan 12, 2023 at 6:43 PM Aleksandr ***@***.***> wrote:
Hi all , has anyone been able to use NextJS 13 and Apollo Client yet? I'm
starting a new project and really want to do it on NextJS 13, but I need
tools to work with GraphQL.
—
Reply to this email directly, view it on GitHub
<#10344 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AOHWIQIFU2NAYVDH4OZBLT3WSA7ENANCNFSM6AAAAAASZL4AY4>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
--
Lloyd Richards
*Data Visualization Designer*
+41 7797 30938
www.lloydrichardsdesign.com
|
But then NextJS will work like regular React, right? And for my project SEO is very important.
|
It is possible to make calls from the server side. I've been using the same setup for I've found this way works for hitting a GraphQL API directly, but it doesn't do server-side caching, so it makes requests each time (I think). In my case I need to make this call in
import { getPostBySlug } from '@/queries/wordpress/getPostBySlug'
import { ArticleContentHtml } from '@/components/articles/ArticleContent'
import { ArticleHeader } from '@/components/articles/ArticleHeader'
interface PageProps {
params: any
children?: React.ReactNode
}
export const revalidate = 60 * 60 // 60 minutes
export default async function Page({ params }: PageProps) {
const article = await getPostBySlug(params.slug)
if (!article) return null
return (
<>
<ArticleHeader article={article} />
<ArticleContentHtml article={article} />
</>
)
}
import wordpressClient, { parsePost } from '@/lib/wordpressClient'
import { gql } from '@apollo/client'
export const findWordpressPost = gql`
query GetWordPressPost($slug: String!) {
post: postBy(slug: $slug) {
title
}
}
`
export const getPostBySlug = (slug: string) => {
return wordpressClient
.query({
query: findWordpressPost,
variables: {
slug,
},
})
.then((result) => {
if (!result.data.post) {
return null
}
return parsePost(result.data.post)
})
}
import { ApolloClient, createHttpLink, InMemoryCache } from '@apollo/client'
import { setContext } from '@apollo/client/link/context'
const clientHttpLink = createHttpLink({
uri: 'https://wp.adamfortuna.com/graphql',
})
const clientAuthLink = setContext((_, { headers }) => {
return {
headers: {
...headers,
authorization: `Basic ${process.env.WP_ADAMFORTUNA_TOKEN}`,
},
}
})
const client = new ApolloClient({
link: clientAuthLink.concat(clientHttpLink),
cache: new InMemoryCache(),
})
export default client This is pretty basic, but it allows for using GraphQL with Apollo, with an authenticated API. I'm still working on having Next.js 13 cache the network call from |
@adamfortuna Hey Adams, that's what i'm doing too, but for me the revalidate doesn't work after build, does it for you? For the cache, did you try with the defaultOptions? : const client = new ApolloClient({
uri: `http://localhost:3000/api/graphql`,
cache: new InMemoryCache(),
defaultOptions: {
watchQuery: {
fetchPolicy: "cache-and-network",
errorPolicy: "none",
},
query: {
fetchPolicy: "network-only",
errorPolicy: "all",
},
},
}); |
@baxterw3b What expected behavior are you referring to that is not working? There are some interesting gotchas with |
Any new advances on this? Still getting: |
I would expect that if i set a revalidate of 10 seconds after those 10 seconds if i refresh the page that data would be new, instead i had the cached data. |
Looking at this more, I guess the Next.js @jerelmiller @bignimbus Maybe a new API for Apollo Client + React Server Components is is needed, especially to enable scenarios such as:
This scenario is described further in Handling Apollo Client Cache Hydration in Next.js 13's app directory #10466 Other libraries using context also have this issue, eg. Emotion, where there will also be an investigation of providing a special API for Server Components. |
@lloydrichards out of curiosity, are you using |
Hey, everyone, I found a solution (workaround). 1. First off we need to extend Apollo client and add some additional functionality to it. You may not do it exactly this way. The main idea is to save query promises when you call each query: (in my approach they are stored in the
2. Then create such a component:
3. Lastly, render this component at the bottom of your tree in the main layout.
Please note that this is only a demo. It extends only the Side note: |
This is such a hack. |
@Gasheck's solution is very clever but has anyone got the |
@pistachiomatt Where exactly do you get an empty object? In your browser console? Also make sure those components which fetch data use |
Apollo has released some guidance https://www.apollographql.com/blog/apollo-client/how-to-use-apollo-client-with-next-js-13/ |
@patrick91 thanks for this blog post! Does this share the cache between Server Components and Client Components? Seems like it does not... 🤔 So maybe it does not have a lot of the optimizations discussed in this thread here yet... |
@karlhorky you're right, the blog post is mostly about using RSC with Apollo. My understanding is that since Server Components are only executed in the server, sharing the Apollo Cache might not be that useful, as the server component won't re-render when the cache changes. I'm looking into a follow-up blog post on how to share the cache, I'll probably based it on @Gasheck findings (thanks for that), but as I said above, the Server Components' code won't be sent, so we'd need to find another solution there. I know the vercel team is working on an RFC for mutations, maybe there's something there for us 😊 We are also experimenting with making some utilities for Next.js to reduce the code you have to write to make Apollo Client work properly there, but I'm not sure when that will be ready 😊 |
Does anyone know what would be the ideal pattern to use fetchMore for pagination with RSC? |
I'm trying to build this as we speak, this is the direction I'm going:
|
For the problem that has been mentioned in the first post here,
You can use the experiential build from over in #10726: npm i @apollo/client@0.0.0-pr-10726-20230405113624 More experimentation around this and a RFC will likely drop within the next few weeks. |
I would like to improve on this implementation by integrating with standard JS practices a bit better. My difference is that I have created my own Downside to this approach that I've seen people say (haven't tested myself) is that revalidation doesn't work (There seems to be a large discussion about how to implement Streaming and revalidation on the RFC for React 18) and the cache isn't working? In the meantime I'd say this is a good solution given that the beta for 3.8.0 is scheduled to release in 15d |
@robigan thanks for sharing!
I presume that since you're using If you don't need to respond to those kinds of cache updates, then this is a totally reasonable solution! There just happens to be some additional complexity to consider here as well, which is what makes this so tricky. Food for thought! FWIW this is something the upcoming
It's not so much that the cache isn't working, its more that there is a lot of added complexity in React 18 and Suspense that we previously didn't have. In React 17 and prior, rendering was synchronous. This meant rendering your app in SSR was done in a single pass. Apollo's SSR approach took advantage of this by waiting for all your queries to settle before the HTML was generated and sent to the browser. Because we could wait for all queries to settle, this meant we could serialize the entire cache and send it to the browser along with the rest of your app's HTML. This allowed the browser to hydrate the Apollo cache using the data fetched on the server. This client cache hydration was necessary to prevent your client components from fetching again, since your server already did the work. In React 18, there is no longer a synchronous rendering model. React now has the superpower to stream HTML updates from the server to the client incrementally as parts of your app are ready to be displayed. React determines these "boundaries" by using Suspense. Because parts of your app might now be sent to the browser while other parts are still executing on the server, we can no longer wait for all queries to settle before we can send the cache results to the browser. And this is the problem we are trying to solve now. We need to be able to incrementally stream those cache updates from the server to the browser to prevent the client from re-executing those queries. This allows us to avoid refetching those queries on the client when React hydrates those components. Ideally a lot of this complexity is hidden away from you. That was a ton of info, but hopefully that helps you understand where we are at! We will have a public RFC that goes over this a lot more in detail in the coming week or two. We'll be sure to post an update in the original RFC (and likely here) if you're interested in learning more. |
Hey, @lloydrichards. Were you able to use |
Just want to clarify for future reference that use is server based and should be server based fwik. All use does is accept a promise and wait for it to finish, triggering suspense while the promise resolves. |
the dashboard i was working on ended up only getting the data from the server components and then passed things down to my charts and interactive elements that were client side. I've been waiting for some more clarity on RSC in general as Next has a very opinionated way of using them which i'm not sure how other libraries will follow if they support other frameworks using different patterns 🤷 |
I'm also building a dashboard with interactive elements like filters. I thought I had to get data in the same client components. Do you happen to have a sample in a public repo that I can use as a reference? |
Hey everyone, I just wanted to let you all know that we released a package to support React Server Components and the new streaming SSR for Client Components that the Next.js App router offers. You can find the package repository over here: @apollo/experimental-nextjs-app-support I will be closing this issue here and would love it if you could give us feedback and suggestions for improvements over in the other repo! |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Intended outcome:
After moving my app from the pages layout to the new app directory, I should be able to make simple queries to my GraphQL endpoint using
apollo-client
andgraphql-codegen
Actual outcome:
With the new NextJS 13 server rendered components, its no longer possible to provide the apollo context at the root of the app and then useQuery() to fetch the data.
How to reproduce the issue:
I initially tried to match up the pageProps that I was using in the previous version:
config/apolloClient.ts
pages/_app.tsx
With the new Next13 AppDir they suggest creating a provider.tsx which is rendered client side and used to wrap the children in the layout.tsx as stated in their docs, but since i'm adding the apollo state to the app in my useApollo() this doesn't work.
So i've tried to make a simplier version by following some other blog posts on using Next and Apollo to initialize the client and then try useQuery() in a RSC:
config/apollo_config.ts
app/providers.tsx
When running on a server rendered component i get the following error:
and if i run it on a client rendered component i get:
At this point i'm just kind walking around in the dark as i can't really wrap my head around what needs to be happening in order for the app to work with client rendered and server rendered components and where apollo client fits in to get my graphql data that i need.
Any suggestions or links to working examples for someone using Next JS 13 + AppDir + ApolloClient would be much appreciated!
Versions
The text was updated successfully, but these errors were encountered: