diff --git a/web/src/app/api/agents/route.ts b/web/src/app/api/agents/route.ts
index 23431c1e20..ec86a22feb 100644
--- a/web/src/app/api/agents/route.ts
+++ b/web/src/app/api/agents/route.ts
@@ -6,8 +6,8 @@ import { unstable_cache } from 'next/cache'
import { logger } from '@/util/logger'
-// Cache for 60 seconds with stale-while-revalidate
-export const revalidate = 60
+// Enable static generation for API route
+export const revalidate = 600 // Cache for 10 minutes
// Cached function for expensive agent aggregations
const getCachedAgents = unstable_cache(
@@ -251,7 +251,7 @@ const getCachedAgents = unstable_cache(
},
['agents-data'],
{
- revalidate: 60,
+ revalidate: 60 * 10, // Cache for 10 minutes
tags: ['agents'],
}
)
@@ -265,9 +265,13 @@ export async function GET() {
// Add cache headers for CDN and browser caching
response.headers.set(
'Cache-Control',
- 'public, max-age=60, s-maxage=60, stale-while-revalidate=300'
+ 'public, max-age=600, s-maxage=600, stale-while-revalidate=600'
)
+ // Add additional headers for better CDN caching
+ response.headers.set('Vary', 'Accept-Encoding')
+ response.headers.set('X-Content-Type-Options', 'nosniff')
+
return response
} catch (error) {
logger.error({ error }, 'Error fetching agents')
diff --git a/web/src/app/store/page.tsx b/web/src/app/store/page.tsx
index 0b34f043ab..9a33a86c39 100644
--- a/web/src/app/store/page.tsx
+++ b/web/src/app/store/page.tsx
@@ -1,7 +1,5 @@
import { Suspense } from 'react'
import { Metadata } from 'next'
-import { getServerSession } from 'next-auth/next'
-import { authOptions } from '@/app/api/auth/[...nextauth]/auth-options'
import { unstable_cache } from 'next/cache'
import AgentStoreClient from './store-client'
@@ -84,21 +82,19 @@ export const metadata: Metadata = {
},
}
-// Enable static generation with revalidation
-export const revalidate = 60
+// Enable static site generation with ISR
+export const revalidate = 60 * 10 // Revalidate every hour
interface StorePageProps {
searchParams: { [key: string]: string | string[] | undefined }
}
export default async function StorePage({ searchParams }: StorePageProps) {
- // Get session for conditional rendering
- const session = await getServerSession(authOptions)
-
- // Fetch agents data at build time / on revalidation
+ // Fetch agents data at build time
const agentsData = await getCachedAgentsData()
- // For now, pass empty array for publishers - client will handle this
+ // For static generation, we don't pass session data
+ // The client will handle authentication state
const userPublishers: PublisherProfileResponse[] = []
return (
@@ -106,7 +102,7 @@ export default async function StorePage({ searchParams }: StorePageProps) {
diff --git a/web/src/app/store/store-client.tsx b/web/src/app/store/store-client.tsx
index d5e72aa034..978303d9a2 100644
--- a/web/src/app/store/store-client.tsx
+++ b/web/src/app/store/store-client.tsx
@@ -3,6 +3,7 @@
import { useState, useMemo, useCallback, memo, useEffect, useRef } from 'react'
import { useQuery } from '@tanstack/react-query'
import { useWindowVirtualizer } from '@tanstack/react-virtual'
+import { useSession } from 'next-auth/react'
import {
Search,
TrendingUp,
@@ -29,7 +30,7 @@ import {
SelectValue,
} from '@/components/ui/select'
import { toast } from '@/components/ui/use-toast'
-import { formatRelativeTime } from '@/lib/date-utils'
+import { RelativeTime } from '@/components/ui/relative-time'
import { cn } from '@/lib/utils'
import { useResponsiveColumns } from '@/hooks/use-responsive-columns'
import type { Session } from 'next-auth'
@@ -93,9 +94,12 @@ const EDITORS_CHOICE_AGENTS = [
export default function AgentStoreClient({
initialAgents,
initialPublishers,
- session,
+ session: initialSession,
searchParams,
}: AgentStoreClientProps) {
+ // Use client-side session for authentication state
+ const { data: clientSession } = useSession()
+ const session = clientSession || initialSession
const [searchQuery, setSearchQuery] = useState(
(searchParams.search as string) || ''
)
@@ -403,7 +407,7 @@ export default function AgentStoreClient({
className="text-xs text-muted-foreground/60"
title={new Date(agent.last_used).toLocaleString()}
>
- Used {formatRelativeTime(agent.last_used)}
+ Used
)}
diff --git a/web/src/components/ui/relative-time.tsx b/web/src/components/ui/relative-time.tsx
new file mode 100644
index 0000000000..8712596b74
--- /dev/null
+++ b/web/src/components/ui/relative-time.tsx
@@ -0,0 +1,32 @@
+'use client'
+
+import { useState, useEffect } from 'react'
+import { formatRelativeTime } from '@/lib/date-utils'
+
+interface RelativeTimeProps {
+ date: string
+}
+
+export function RelativeTime({ date }: RelativeTimeProps) {
+ const [isClient, setIsClient] = useState(false)
+ const [relativeTime, setRelativeTime] = useState('')
+
+ useEffect(() => {
+ setIsClient(true)
+ setRelativeTime(formatRelativeTime(date))
+
+ // Update every minute to keep relative time fresh
+ const interval = setInterval(() => {
+ setRelativeTime(formatRelativeTime(date))
+ }, 60000)
+
+ return () => clearInterval(interval)
+ }, [date])
+
+ // Show absolute date on server, relative time on client
+ if (!isClient) {
+ return <>{new Date(date).toLocaleDateString()}>
+ }
+
+ return <>{relativeTime}>
+}