From ea28dcde91b437e743847ea9cbd45291d14a123f Mon Sep 17 00:00:00 2001 From: Travis Fischer Date: Tue, 1 Jul 2025 08:02:21 -0500 Subject: [PATCH] feat(web): fix example usage hydration error --- apps/web/src/app/providers.tsx | 36 +++++++++++++++++++++-- apps/web/src/components/example-usage.tsx | 24 ++++++++++----- apps/web/src/lib/query-client.ts | 3 -- 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/apps/web/src/app/providers.tsx b/apps/web/src/app/providers.tsx index cfe0c51c..ab57a1f0 100644 --- a/apps/web/src/app/providers.tsx +++ b/apps/web/src/app/providers.tsx @@ -1,16 +1,46 @@ 'use client' -import type React from 'react' -import { QueryClientProvider } from '@tanstack/react-query' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import { AgenticProvider } from '@/components/agentic-provider' import { PostHogProvider } from '@/components/posthog-provider' import { ThemeProvider } from '@/components/theme-provider' import { TooltipProvider } from '@/components/ui/tooltip' -import { queryClient } from '@/lib/query-client' +import { isServer } from '@/lib/config' + +function createQueryClient() { + return new QueryClient({ + defaultOptions: { + queries: { + staleTime: 60 * 1000 + } + } + }) +} + +let browserQueryClient: QueryClient | undefined + +function getQueryClient(): QueryClient { + if (isServer) { + // Server: always make a new query client + return createQueryClient() + } else { + // Browser: make a new query client if we don't already have one + // This is very important, so we don't re-make a new client if React + // suspends during the initial render. This may not be needed if we + // have a suspense boundary BELOW the creation of the query client + if (!browserQueryClient) { + browserQueryClient = createQueryClient() + } + + return browserQueryClient + } +} export default function Providers({ children }: { children: React.ReactNode }) { + const queryClient = getQueryClient() + return ( diff --git a/apps/web/src/components/example-usage.tsx b/apps/web/src/components/example-usage.tsx index 9885b04c..525aa795 100644 --- a/apps/web/src/components/example-usage.tsx +++ b/apps/web/src/components/example-usage.tsx @@ -1,7 +1,7 @@ 'use client' import type { Project } from '@agentic/platform-types' -import type { JSX } from 'react' +import { type JSX, useEffect, useMemo, useState } from 'react' import { useLocalStorage } from 'react-use' import { useAgentic } from '@/components/agentic-provider' @@ -43,12 +43,22 @@ export function ExampleUsage({ initialCodeBlock?: JSX.Element }) { const ctx = useAgentic() + const [isMounted, setIsMounted] = useState(false) - const [config, setConfig] = useLocalStorage( + useEffect(() => { + setIsMounted(true) + }, []) + + const [rawConfig, setConfig] = useLocalStorage( 'developer-config', defaultConfig ) + const config = useMemo( + () => (isMounted && rawConfig ? rawConfig : defaultConfig), + [rawConfig, isMounted] + ) + // TODO: make this configurable // TODO: allow to take the project and/or consumer in as props // TODO: need a way of fetching a project and target deployment; same as in `AgenticToolClient.fromIdentifier` (currently only supports latest) @@ -151,7 +161,7 @@ function ExampleUsageContent({ return ( setConfig({ ...defaultConfig, @@ -176,7 +186,7 @@ function ExampleUsageContent({ setConfig({ ...defaultConfig, @@ -216,7 +226,7 @@ function ExampleUsageContent({ setConfig({ ...defaultConfig, @@ -252,7 +262,7 @@ function ExampleUsageContent({ setConfig({ ...defaultConfig, @@ -288,7 +298,7 @@ function ExampleUsageContent({ setConfig({ ...defaultConfig, diff --git a/apps/web/src/lib/query-client.ts b/apps/web/src/lib/query-client.ts index 12827078..cdaf62c1 100644 --- a/apps/web/src/lib/query-client.ts +++ b/apps/web/src/lib/query-client.ts @@ -1,15 +1,12 @@ import { type DefaultError, type InfiniteData, - QueryClient, type QueryKey, useInfiniteQuery as useInfiniteQueryBase, useQuery as useQueryBase } from '@tanstack/react-query' import { HTTPError } from 'ky' -export const queryClient = new QueryClient() - const retryStatusCodes = new Set([408, 413, 429, 500, 502, 503, 504]) // Inspired by https://github.com/sindresorhus/ky#retry