diff --git a/apps/web/next-env.d.ts b/apps/web/next-env.d.ts
index 830fb594..7506fe6a 100644
--- a/apps/web/next-env.d.ts
+++ b/apps/web/next-env.d.ts
@@ -1,6 +1,6 @@
///
///
-///
+import "./.next/dev/types/routes.d.ts"
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
diff --git a/apps/web/next.config.mjs b/apps/web/next.config.mjs
index c3567c78..2f40dca5 100644
--- a/apps/web/next.config.mjs
+++ b/apps/web/next.config.mjs
@@ -1,8 +1,9 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
basePath: "/watch",
+ typedRoutes: true,
experimental: {
- typedRoutes: true,
+ useCache: true,
},
}
diff --git a/apps/web/src/app/api/revalidate/route.ts b/apps/web/src/app/api/revalidate/route.ts
index c4844235..261bb60f 100644
--- a/apps/web/src/app/api/revalidate/route.ts
+++ b/apps/web/src/app/api/revalidate/route.ts
@@ -1,6 +1,16 @@
-import { revalidatePath } from "next/cache"
+import { revalidateTag } from "next/cache"
import { NextResponse } from "next/server"
+interface StrapiWebhookPayload {
+ event: string
+ model: string
+ entry?: {
+ slug?: string
+ locale?: string
+ documentId?: string
+ }
+}
+
export async function POST(request: Request) {
const token = request.headers.get("x-forge-revalidate-token")
if (
@@ -13,8 +23,11 @@ export async function POST(request: Request) {
)
}
- const body = (await request.json().catch(() => ({}))) as { path?: string }
- const path = body.path ?? "/"
- revalidatePath(path)
- return NextResponse.json({ revalidated: true, path })
+ const body = (await request.json().catch(() => ({}))) as StrapiWebhookPayload
+ const slug = body.entry?.slug
+ const tag = slug ? `experience:${slug}` : "experience"
+
+ revalidateTag(tag, "max")
+
+ return NextResponse.json({ revalidated: true, tag })
}
diff --git a/apps/web/src/lib/content.ts b/apps/web/src/lib/content.ts
index 1f3348cc..4d1249b7 100644
--- a/apps/web/src/lib/content.ts
+++ b/apps/web/src/lib/content.ts
@@ -1,3 +1,4 @@
+import { cacheTag, cacheLife } from "next/cache"
import { graphql } from "@forge/graphql"
import client from "@/lib/client"
@@ -10,12 +11,21 @@ const GET_EXPERIENCE = graphql(`
`)
export async function readPublishedContent(slug: string, locale: string) {
+ "use cache"
+
+ cacheTag("experience", `experience:${slug}`, `experience:${slug}:${locale}`)
+ cacheLife("max")
+
if (!process.env.NEXT_PUBLIC_GRAPHQL_URL) return null
- const result = await client.query({
- query: GET_EXPERIENCE,
- variables: { slug, locale },
- })
- if (result.error) return null
- const items = result.data?.experiences
- return items?.[0] ?? null
+ try {
+ const result = await client.query({
+ query: GET_EXPERIENCE,
+ variables: { slug, locale },
+ })
+ if (result.error) return null
+ const items = result.data?.experiences
+ return items?.[0] ?? null
+ } catch {
+ return null
+ }
}
diff --git a/package.json b/package.json
index 937ce737..9c549a21 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,8 @@
"prepare": "husky",
"build": "turbo run build",
"dev": "turbo run dev --parallel",
+ "dev:web": "turbo run dev --filter=@forge/web",
+ "dev:backend": "turbo run dev --parallel --filter=@forge/cms --filter=@forge/ai-orchestrator",
"lint": "turbo run lint",
"test": "turbo run test",
"codegen": "pnpm --filter @forge/graphql run generate",
@@ -29,4 +31,4 @@
"turbo": "^2.8.9",
"typescript-eslint": "^8.56.0"
}
-}
+}
\ No newline at end of file
diff --git a/turbo.json b/turbo.json
index 3d943c0e..8c3e4c97 100644
--- a/turbo.json
+++ b/turbo.json
@@ -25,6 +25,9 @@
},
"validate": {
"dependsOn": ["^validate"]
+ },
+ "generate": {
+ "outputs": ["src/graphql-env.d.ts"]
}
}
}