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

Next.js Cache (beta) #725

Open
yannxaver opened this issue Mar 10, 2023 · 5 comments
Open

Next.js Cache (beta) #725

yannxaver opened this issue Mar 10, 2023 · 5 comments
Labels
documentation Improvements or additions to documentation

Comments

@yannxaver
Copy link

Improve documentation

Link

https://supabase.com/docs/reference/javascript/select

Describe the problem

See the release notes here: https://nextjs.org/blog/next-13-2#nextjs-cache

It is not clear how to take advantage of this feature when fetching data with the supabase.js client.

Describe the improvement

Describe how to set the desired cache duration to enable ISR at the component level.

Additional context

None

@yannxaver yannxaver added the documentation Improvements or additions to documentation label Mar 10, 2023
@sannajammeh
Copy link

You can pass a custom fetch function into supabase and it works.

First create a fetch factory function that takes next cache properties as parameters:

// utils/cache.ts

export const createFetch =
  (options: Pick<RequestInit, "next" | "cache">) =>
  (url: RequestInfo | URL, init?: RequestInit) => {
    return fetch(url, {
      ...init,
      ...options,
    });
  };

Then in your RSC:

import { createFetch } from "@/utils/cache";
  
const supabase = createServerComponentClient({ cookies }, {
    options: {
      global: {
        fetch: createFetch({
          cache: "no-store"
        })
      }
    }
});

@RyelBanfield
Copy link

RyelBanfield commented Jun 20, 2023

"Good to know: cookies() is a Dynamic Function whose returned values cannot be known ahead of time. Using it in a layout or page will opt a route into dynamic rendering at request time."

Any way we get around this?

Edit: This might be helpful

@sannajammeh
Copy link

"Good to know: cookies() is a Dynamic Function whose returned values cannot be known ahead of time. Using it in a layout or page will opt a route into dynamic rendering at request time."

Any way we get around this?

Edit: This might be helpful

Yes. Just use the regular supabase client. Create a wrapper like above using only Supabase createClient and service key.

The pre-requisite is that you don't use any auth on the server in that case as that requires the page to be SSR/dynamic rendered.

@cachho
Copy link

cachho commented Jan 26, 2024

Great snippet! Is anyone able to tell me why the first request isn't getting cached? It looks pretty identical to the third one to me. I'm using a regular refresh with F5 in next dev.

Code:

  const supabase = createClient<Database>(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.SUPABASE_SERVICE_KEY!,
    {
      global: {
        fetch: createFetch({
          next: {
            revalidate: 1800,
          },
        }),
      },
    }
  );

  const { count: items } = await supabase
    .from('sheetsItem')
    .select('*', { count: 'estimated', head: true })
    .eq('active', true);

  const { data: itemsMarketplace } = await supabase.rpc('count_distinct_items');

  const { count: spreadsheets } = await supabase
    .from('sheetsSheet')
    .select('*', { count: 'exact', head: true })
    .eq('active', true);

Logs:

GET /search/spreadsheet200 in 9540ms
  │ HEAD https://api.example.com/rest/v1/sheetsItem?select=*&active=eq.true 206 in 6898ms (cache: SKIP)
  │  │  Cache missed reason: (cache-control: no-cache (hard refresh))
  │  │ HEAD https://api.example.com/rest/v1/sheetsSheet?select=*&active=eq.true 200 in 2ms (cache: HIT)
  │  │ POST https://api.example.com/rest/v1/rpc/count_distinct_items 200 in 0ms (cache: HIT)

@sannajammeh
Copy link

Great snippet! Is anyone able to tell me why the first request isn't getting cached? It looks pretty identical to the third one to me. I'm using a regular refresh with F5 in next dev.

Code:

  const supabase = createClient<Database>(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.SUPABASE_SERVICE_KEY!,
    {
      global: {
        fetch: createFetch({
          next: {
            revalidate: 1800,
          },
        }),
      },
    }
  );

  const { count: items } = await supabase
    .from('sheetsItem')
    .select('*', { count: 'estimated', head: true })
    .eq('active', true);

  const { data: itemsMarketplace } = await supabase.rpc('count_distinct_items');

  const { count: spreadsheets } = await supabase
    .from('sheetsSheet')
    .select('*', { count: 'exact', head: true })
    .eq('active', true);

Logs:

GET /search/spreadsheet200 in 9540ms
  │ HEAD https://api.example.com/rest/v1/sheetsItem?select=*&active=eq.true 206 in 6898ms (cache: SKIP)
  │  │  Cache missed reason: (cache-control: no-cache (hard refresh))
  │  │ HEAD https://api.example.com/rest/v1/sheetsSheet?select=*&active=eq.true 200 in 2ms (cache: HIT)
  │  │ POST https://api.example.com/rest/v1/rpc/count_distinct_items 200 in 0ms (cache: HIT)

Caching works different in Next.js dev-mode and production

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

4 participants