Skip to main content
Glama
ReactQueryProvider.tsx3.39 kB
'use client'; import { type DefaultOptions, MutationCache, QueryClient, QueryClientProvider, type QueryKey, type UseMutationOptions, } from '@tanstack/react-query'; import { type FC, type PropsWithChildren, useRef } from 'react'; import { useToast } from '../components/Toaster'; const defaultQueryOptions: DefaultOptions = { queries: { retry: 1, staleTime: 0, // Give the cache a little breathing room across route transitions: gcTime: 5 * 60 * 1000, // e.g. 5 minutes // You likely want to refetch on mount if data is stale (default is true). // Remove your overrides or force it: refetchOnMount: 'always', refetchOnWindowFocus: false, refetchOnReconnect: false, }, mutations: { retry: 0, }, }; declare module '@tanstack/react-query' { interface Register { mutationMeta: { onSuccess?: UseMutationOptions['onSuccess']; onError?: UseMutationOptions['onError']; invalidateQueries?: QueryKey[]; resetQueries?: QueryKey[]; }; } } const formatErrorCode = (errorCode: string) => errorCode.split('_').join(' '); /** * Hook to handle error logging and toast notifications */ const useToastEvents = () => { const { toast } = useToast(); const onError: MutationCache['config']['onError'] = (error: any) => { const parsed = (() => { try { if (typeof error === 'string') return JSON.parse(error); } catch (_) {} return error; })(); [parsed].flat().forEach((err: any) => { toast({ title: formatErrorCode( (process.env.NODE_ENV === 'production' ? err?.title : err?.code) ?? 'Error' ), description: err?.message ?? String(err ?? 'An error occurred'), variant: 'error', }); }); }; const onSuccess: MutationCache['config']['onSuccess'] = (data: any) => { if (data?.error) { toast({ title: formatErrorCode(data.error.title ?? data.error.code ?? 'Error'), description: data.error.message ?? data.error.code ?? 'An error occurred', variant: 'error', }); } if (data?.message) { toast({ title: data.message, description: data.description, variant: 'success', }); } }; return { onError, onSuccess, }; }; export const ReactQueryProvider: FC<PropsWithChildren> = ({ children }) => { const { onError, onSuccess } = useToastEvents(); const clientRef = useRef<QueryClient>(null); if (!clientRef.current) { const mutationCache = new MutationCache({ onSuccess, onError, onSettled: (_data, _error, _variables, _context, mutation) => { if (mutation.meta?.invalidateQueries) { mutation.meta.invalidateQueries.forEach((queryKey) => { queryClient.invalidateQueries({ queryKey, }); }); } if (mutation.meta?.resetQueries) { mutation.meta.resetQueries.forEach((queryKey) => { queryClient.resetQueries({ queryKey, }); }); } }, }); const queryClient = new QueryClient({ defaultOptions: defaultQueryOptions, mutationCache, }); clientRef.current = queryClient; } return ( <QueryClientProvider client={clientRef.current}> {children} </QueryClientProvider> ); };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aymericzip/intlayer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server