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

DynamicServerError at build time when cache: no-store is enabled #339

Open
mpotane opened this issue Aug 4, 2024 · 8 comments
Open

DynamicServerError at build time when cache: no-store is enabled #339

mpotane opened this issue Aug 4, 2024 · 8 comments
Labels
bug Something isn't working

Comments

@mpotane
Copy link

mpotane commented Aug 4, 2024

export const { query } = registerApolloClient(() => {
  return new ApolloClient({
    cache: new InMemoryCache(),
    link: new HttpLink({
      uri: "https://api.github.com/graphql",
      // you can disable result caching here if you want to
      // (this does not work if you are rendering your page with `export const dynamic = "force-static"`)
      fetchOptions: { cache: "no-store" }, // --enabled
      headers: {
        authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
      },
    }),
  });
});
@phryneas
Copy link
Member

phryneas commented Aug 5, 2024

Hi Mark,
could you please add a little bit more explanation?

Generally, if you force your page to be generated statically and then make a dynamic request like this, Next.js will error, as these two modes cannot exist at the same time.

I assume that's what's happening here - but with more context I can't help you.

@Tagir-A
Copy link

Tagir-A commented Dec 18, 2024

Hey @phryneas I have a similar issue, maube this is related. Let me give you more background.

Basically, follow this blog post from Apollo to setup apollo client with next. And then if you look at server component part, you will see a similar snippet.

import { ApolloClient, HttpLink, InMemoryCache } from "@apollo/client";
import { registerApolloClient } from "@apollo/experimental-nextjs-app-support/rsc";

export const { getClient } = registerApolloClient(() => {
  return new ApolloClient({
    cache: new InMemoryCache(),
    link: new HttpLink({
      // https://studio.apollographql.com/public/spacex-l4uc6p/
      uri: "https://main--spacex-l4uc6p.apollographos.net/graphql",
      // you can disable result caching here if you want to
      // (this does not work if you are rendering your page with `export const dynamic = "force-static"`)
      // fetchOptions: { cache: "no-store" },
    }),
  });
});

In the snippet comments, we are told that we can disable caching by setting cache: no-store.
However, if I uncomment fetchOptions: {cache: "no-store"} and try to use it, during build time I'll get an error from Apollo.

[ApolloError]: Dynamic server usage: no-store fetch

Even though that page is using default dynamic settings of Next.

@phryneas
Copy link
Member

phryneas commented Dec 18, 2024

@Tagir-A I just found this issue: vercel/next.js#46737 (comment)

If you catch errors using try-catch, let errors with error.digest === 'DYNAMIC_SERVER_USAGE' pass through unhandled, then everything will work without problems:

It seems that Next.js started using this error to detect dynamic usage. I'm not sure if we can prevent Apollo Client from actually catching these - I'll look into it.

@phryneas phryneas added the bug Something isn't working label Dec 18, 2024
@phryneas
Copy link
Member

I tried reproducing this and I don't see it - you are using export const dynamic = "force-dynamic";, too? That's not enabled in Next by default.

@phryneas
Copy link
Member

You can look at my reproduction here: https://github.com/phryneas/repro_next_dynamic-server-error

Did you do anything differently?

@Tagir-A
Copy link

Tagir-A commented Dec 19, 2024

@phryneas

I tried reproducing this and I don't see it - you are using export const dynamic = "force-dynamic";, too? That's not enabled in Next by default.

Nope, I tried to opt-out of caching on data level by using cache: "no-store"

    const { data, error, loading } = await getApolloClientOnServer().query<{
        content: {
          id
        };
    }>({
        query: QUERY,
        context: {
            fetchOptions: {
                // This should work, but produces an error "ApolloError: Dynamic server usage: no-store fetch"
                cache: 'no-store',
            },
        },
    });

So as a workaround, I can opt-out on route level:

// ...

export const dynamic = 'force-dynamic';

export default function Page() {
// ...
}

This works, but usually I need to opt-out of caching on specific requests, rather than on specific routes.
Cause the route usually contains lots of logic, and if all components which load dynamic data are moved out of the route (due to refactor or user flow change), I want it automatically opt-in to caching. This would be possible if caching is disabled on data level, but it's not possible when it's disabled on route level.

@phryneas
Copy link
Member

I'm honestly unsure at this point if Next.js 15 even supports that anymore - my example was really minimal and it was already failing there :/

@phryneas
Copy link
Member

That said, I think this can be fixed on the Next.js side.
I've opened a PR there: vercel/next.js#74145

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants