Does export const revalidate = work for non fetch based data?
Unanswered
joostschuur posted this in #help-forum
The docs seem to say 'Alternatively, to revalidate all fetch requests in a route segment, you can use the Segment Config Options.', so it looks like the answer is no.
I've set
I've set up an API route that calls
Are there any other options for time based revalidation for data coming from third party libraries where fetch is not used?
I ran into errors using
I've set
export const revalidate = 3600 in a layout.tsx (not a client component) that queries data from Drizzle and then does a Tanstack React Query prefetchQuery and passed that query client via a HydrationBoundary to the browser. Before I read that part of the docs, I assumed that after an hour, the next request would trigger that whole chain of events again, but even after a second page request, I don't see updated data.I've set up an API route that calls
revalidatePath('/'), which seems to do the trick, but this of course relies on a cron trigger for that route e.g..Are there any other options for time based revalidation for data coming from third party libraries where fetch is not used?
I ran into errors using
unstable_cache during the build process, and using React's own cache doesn't let you specify an expiration time.5 Replies
@Ray hi, `revalidate` should work there. are you using route handler with `useQuery` on client side?
Client side, I'm just calling a server action in
But when I visit the page, it's not even showing the loading spinner as a sign that it's making a new request.
Obviously on the client side, it says
useQuery in a custom hook: const query = useQuery({
queryKey: ['videos', filterOptions],
queryFn: () => getLatestVideos(filterOptions as FilterOptions),
staleTime: Infinity,
});But when I visit the page, it's not even showing the loading spinner as a sign that it's making a new request.
Obviously on the client side, it says
staleTime: Infinity here, but on a new page refresh/load, that React Query cache is blown away anyway.Here's my whole
layout.tsx:import { HydrationBoundary, QueryClient, dehydrate } from '@tanstack/react-query';
import { GeistSans } from 'geist/font/sans';
import type { Metadata } from 'next';
import { Suspense } from 'react';
import '@/styles/globals.css';
import Providers from '@/components/Providers';
import { HomepageProvider } from '@/components/context';
import Header from '@/components/site/Header';
import { resetState } from '@/lib/filter';
import { getLatestVideos } from '@/db/queries';
import { cn } from '@/lib/utils';
export const metadata: Metadata = {
title: 'LearnByVideo.dev - Find the best development videos',
description: 'Find the best development videos to learn from.',
};
export const revalidate = 3600;
const recentVideos = await getLatestVideos();
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 60 * 1000,
refetchOnWindowFocus: false,
},
},
});
await queryClient.prefetchQuery({
queryKey: ['videos', resetState],
queryFn: () => recentVideos,
});
const dehydratedState = dehydrate(queryClient);
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang='en' suppressHydrationWarning>
<Providers>
<HydrationBoundary state={dehydratedState}>
<body
className={cn('min-h-screen bg-violet-50 font-sans antialiased', GeistSans.variable)}
>
<Suspense fallback={null}>
<HomepageProvider>
<Header />
<main className='container mx-auto px-4 sm:px-10 py-4'>{children}</main>
</HomepageProvider>
</Suspense>
</body>
</HydrationBoundary>
</Providers>
</html>
);
}I assumed revalidating, means also rerunning the code at the root scope of this file (not just in
RootLayout), so it makes a fresh getLatestVideos call and prefetches etc...@joostschuur Here's my whole `layout.tsx`:
ts
import { HydrationBoundary, QueryClient, dehydrate } from '@tanstack/react-query';
import { GeistSans } from 'geist/font/sans';
import type { Metadata } from 'next';
import { Suspense } from 'react';
import '@/styles/globals.css';
import Providers from '@/components/Providers';
import { HomepageProvider } from '@/components/context';
import Header from '@/components/site/Header';
import { resetState } from '@/lib/filter';
import { getLatestVideos } from '@/db/queries';
import { cn } from '@/lib/utils';
export const metadata: Metadata = {
title: 'LearnByVideo.dev - Find the best development videos',
description: 'Find the best development videos to learn from.',
};
export const revalidate = 3600;
const recentVideos = await getLatestVideos();
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 60 * 1000,
refetchOnWindowFocus: false,
},
},
});
await queryClient.prefetchQuery({
queryKey: ['videos', resetState],
queryFn: () => recentVideos,
});
const dehydratedState = dehydrate(queryClient);
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang='en' suppressHydrationWarning>
<Providers>
<HydrationBoundary state={dehydratedState}>
<body
className={cn('min-h-screen bg-violet-50 font-sans antialiased', GeistSans.variable)}
>
<Suspense fallback={null}>
<HomepageProvider>
<Header />
<main className='container mx-auto px-4 sm:px-10 py-4'>{children}</main>
</HomepageProvider>
</Suspense>
</body>
</HydrationBoundary>
</Providers>
</html>
);
}
hmm, try move the queryClient inside the
RootLayoutexport default async function RootLayout({ children }: { children: React.ReactNode }) {
const queryClient = new QueryClient();
await queryClient.prefetchQuery({
queryKey: ['videos', resetState],
queryFn: async () => getLatestVideos(),
});
const dehydratedState = dehydrate(queryClient);
return (
<html lang='en' suppressHydrationWarning>
<Providers>
<HydrationBoundary state={dehydratedState}>
<body
className={cn('min-h-screen bg-violet-50 font-sans antialiased', GeistSans.variable)}
>
<Suspense fallback={null}>
<HomepageProvider>
<Header />
<main className='container mx-auto px-4 sm:px-10 py-4'>{children}</main>
</HomepageProvider>
</Suspense>
</body>
</HydrationBoundary>
</Providers>
</html>
);
}