diff --git a/frontend/app/api/analytics/events/route.ts b/frontend/app/api/analytics/events/route.ts index 73f8bb8c..4a895a2a 100644 --- a/frontend/app/api/analytics/events/route.ts +++ b/frontend/app/api/analytics/events/route.ts @@ -5,8 +5,14 @@ import { } from "@/lib/backend-auth"; const API_BASE = process.env.POLYWEATHER_API_BASE_URL; +const ANALYTICS_ENABLED = + process.env.NEXT_PUBLIC_POLYWEATHER_APP_ANALYTICS === "true"; export async function POST(req: NextRequest) { + if (!ANALYTICS_ENABLED) { + return new NextResponse(null, { status: 204 }); + } + if (!API_BASE) { return NextResponse.json( { error: "POLYWEATHER_API_BASE_URL is not configured" }, diff --git a/frontend/app/api/cities/route.ts b/frontend/app/api/cities/route.ts index df4c5c3d..6500b8f9 100644 --- a/frontend/app/api/cities/route.ts +++ b/frontend/app/api/cities/route.ts @@ -18,10 +18,15 @@ export async function GET(req: NextRequest) { } try { - const auth = await buildBackendRequestHeaders(req); - const res = await fetch(`${API_BASE}/api/cities`, { + const auth = await buildBackendRequestHeaders(req, { + includeSupabaseIdentity: false, + }); + const fetchOptions = { headers: auth.headers, - cache: "no-store", + next: { revalidate: 300 }, + } as const; + const res = await fetch(`${API_BASE}/api/cities`, { + ...fetchOptions, }); if (!res.ok) { const raw = await res.text(); diff --git a/frontend/app/api/city/[name]/route.ts b/frontend/app/api/city/[name]/route.ts index c0a17fe3..7331cedf 100644 --- a/frontend/app/api/city/[name]/route.ts +++ b/frontend/app/api/city/[name]/route.ts @@ -23,7 +23,9 @@ export async function GET( const url = `${API_BASE}/api/city/${encodeURIComponent(name)}?force_refresh=${forceRefresh}`; try { - const auth = await buildBackendRequestHeaders(req); + const auth = await buildBackendRequestHeaders(req, { + includeSupabaseIdentity: false, + }); const res = await fetch(url, { headers: auth.headers, cache: "no-store", diff --git a/frontend/app/api/city/[name]/summary/route.ts b/frontend/app/api/city/[name]/summary/route.ts index 581387b6..e8f5d634 100644 --- a/frontend/app/api/city/[name]/summary/route.ts +++ b/frontend/app/api/city/[name]/summary/route.ts @@ -25,10 +25,21 @@ export async function GET( const url = `${API_BASE}/api/city/${encodeURIComponent(name)}/summary?force_refresh=${forceRefresh}`; try { - const auth = await buildBackendRequestHeaders(req); + const auth = await buildBackendRequestHeaders(req, { + includeSupabaseIdentity: false, + }); + const fetchOptions = + bypassCache + ? { + headers: auth.headers, + cache: "no-store" as const, + } + : { + headers: auth.headers, + next: { revalidate: 20 }, + }; const res = await fetch(url, { - headers: auth.headers, - cache: "no-store", + ...fetchOptions, }); if (!res.ok) { const raw = await res.text(); diff --git a/frontend/app/api/healthz/route.ts b/frontend/app/api/healthz/route.ts index 66ffb3a1..04515f3a 100644 --- a/frontend/app/api/healthz/route.ts +++ b/frontend/app/api/healthz/route.ts @@ -15,7 +15,9 @@ export async function GET(req: NextRequest) { } try { - const auth = await buildBackendRequestHeaders(req); + const auth = await buildBackendRequestHeaders(req, { + includeSupabaseIdentity: false, + }); const res = await fetch(`${API_BASE}/healthz`, { headers: auth.headers, cache: "no-store", diff --git a/frontend/app/api/history/[name]/route.ts b/frontend/app/api/history/[name]/route.ts index f2d15971..9dec7f4d 100644 --- a/frontend/app/api/history/[name]/route.ts +++ b/frontend/app/api/history/[name]/route.ts @@ -24,9 +24,12 @@ export async function GET( try { const auth = await buildBackendRequestHeaders(req); - const res = await fetch(url, { + const fetchOptions = { headers: auth.headers, - cache: "no-store", + next: { revalidate: 60 }, + } as const; + const res = await fetch(url, { + ...fetchOptions, }); if (!res.ok) { const raw = await res.text(); diff --git a/frontend/app/api/vitals/route.ts b/frontend/app/api/vitals/route.ts index 95f4f284..923607bb 100644 --- a/frontend/app/api/vitals/route.ts +++ b/frontend/app/api/vitals/route.ts @@ -5,6 +5,9 @@ import { recordVitalsSample, } from "@/lib/vitals-store"; +const WEB_VITALS_ENABLED = + process.env.NEXT_PUBLIC_POLYWEATHER_WEB_VITALS === "true"; + type VitalsPayload = { id?: string; metric?: string; @@ -15,6 +18,10 @@ type VitalsPayload = { }; export async function POST(request: Request) { + if (!WEB_VITALS_ENABLED) { + return new NextResponse(null, { status: 204 }); + } + try { const payload = (await request.json()) as VitalsPayload; const metric = normalizeMetricName(payload.metric); @@ -56,6 +63,16 @@ export async function POST(request: Request) { } export async function GET(request: Request) { + if (!WEB_VITALS_ENABLED) { + return NextResponse.json({ + ok: true, + disabled: true, + generatedAt: Date.now(), + sampleCount: 0, + routes: {}, + }); + } + const { searchParams } = new URL(request.url); const targetRoute = String(searchParams.get("route") || "").trim(); const summary = getVitalsSummary(); diff --git a/frontend/app/layout.tsx b/frontend/app/layout.tsx index c8ded1fe..ba441495 100644 --- a/frontend/app/layout.tsx +++ b/frontend/app/layout.tsx @@ -1,5 +1,4 @@ import type { Metadata } from "next"; -import { Analytics } from "@vercel/analytics/react"; import "./globals.css"; export const metadata: Metadata = { @@ -31,10 +30,7 @@ export default function RootLayout({ rel="stylesheet" /> -
- {children} -