diff --git a/app/(main)/(author)/author/[slug]/page.tsx b/app/(main)/(author)/author/[slug]/page.tsx index 886f9d36..889002c6 100644 --- a/app/(main)/(author)/author/[slug]/page.tsx +++ b/app/(main)/(author)/author/[slug]/page.tsx @@ -1,5 +1,5 @@ import type { Metadata, ResolvingMetadata } from "next"; -import { groq, type PortableTextBlock } from "next-sanity"; +import { type PortableTextBlock } from "next-sanity"; import { notFound } from "next/navigation"; import PortableText from "@/components/portable-text"; @@ -9,7 +9,6 @@ import type { AuthorQueryWithRelatedResult, } from "@/sanity/types"; import { sanityFetch } from "@/sanity/lib/live"; -import { client } from "@/sanity/lib/client"; import { authorQuery, authorQueryWithRelated } from "@/sanity/lib/queries"; import { resolveOpenGraphImage } from "@/sanity/lib/utils"; import CoverMedia from "@/components/cover-media"; @@ -20,7 +19,6 @@ import UserRelated from "@/components/user-related"; type Params = Promise<{ slug: string }>; -export const revalidate = 3600; export async function generateMetadata( { params }: { params: Params }, @@ -48,12 +46,6 @@ export async function generateMetadata( } satisfies Metadata; } -export async function generateStaticParams() { - const slugs = await client.fetch( - groq`*[_type == "author" && defined(slug.current)].slug.current`, - ); - return slugs.map((slug) => ({ slug })); -} export default async function AuthorPage({ params }: { params: Params }) { const { slug } = await params; diff --git a/app/(main)/(author)/authors/page/[num]/page.tsx b/app/(main)/(author)/authors/page/[num]/page.tsx index 871b4d0e..b0e3deda 100644 --- a/app/(main)/(author)/authors/page/[num]/page.tsx +++ b/app/(main)/(author)/authors/page/[num]/page.tsx @@ -1,26 +1,15 @@ import MoreContent from "@/components/more-content"; import type { DocCountResult } from "@/sanity/types"; import { sanityFetch } from "@/sanity/lib/live"; -import { client } from "@/sanity/lib/client"; import PaginateList from "@/components/paginate-list"; import { docCount } from "@/sanity/lib/queries"; -import { groq } from "next-sanity"; const LIMIT = 10; type Params = Promise<{ num: string }>; -export const revalidate = 60; -export async function generateStaticParams() { - const count = await client.fetch( - groq`count(*[_type == "author" && defined(slug.current)])`, - ); - const perPage = LIMIT; - const pages = Math.ceil(count / perPage); - return Array.from({ length: pages }, (_, i) => ({ num: String(i + 1) })); -} export default async function Page({ params }: { params: Params }) { const { num } = await params; diff --git a/app/(main)/(guest)/guest/[slug]/page.tsx b/app/(main)/(guest)/guest/[slug]/page.tsx index 6a893a89..b1691d84 100644 --- a/app/(main)/(guest)/guest/[slug]/page.tsx +++ b/app/(main)/(guest)/guest/[slug]/page.tsx @@ -1,5 +1,5 @@ import type { Metadata, ResolvingMetadata } from "next"; -import { groq, type PortableTextBlock } from "next-sanity"; +import { type PortableTextBlock } from "next-sanity"; import { notFound } from "next/navigation"; import PortableText from "@/components/portable-text"; @@ -9,7 +9,6 @@ import type { GuestQueryWithRelatedResult, } from "@/sanity/types"; import { sanityFetch } from "@/sanity/lib/live"; -import { client } from "@/sanity/lib/client"; import { guestQuery, guestQueryWithRelated } from "@/sanity/lib/queries"; import { resolveOpenGraphImage } from "@/sanity/lib/utils"; import CoverMedia from "@/components/cover-media"; @@ -21,7 +20,6 @@ import Avatar from "@/components/avatar"; type Params = Promise<{ slug: string }>; -export const revalidate = 3600; export async function generateMetadata( { params }: { params: Params }, @@ -48,12 +46,6 @@ export async function generateMetadata( } satisfies Metadata; } -export async function generateStaticParams() { - const slugs = await client.fetch( - groq`*[_type == "guest" && defined(slug.current)].slug.current`, - ); - return slugs.map((slug) => ({ slug })); -} export default async function GuestPage({ params }: { params: Params }) { const { slug } = await params; diff --git a/app/(main)/(guest)/guests/page/[num]/page.tsx b/app/(main)/(guest)/guests/page/[num]/page.tsx index d633f12f..f7ceb50f 100644 --- a/app/(main)/(guest)/guests/page/[num]/page.tsx +++ b/app/(main)/(guest)/guests/page/[num]/page.tsx @@ -1,26 +1,15 @@ import MoreContent from "@/components/more-content"; import type { DocCountResult } from "@/sanity/types"; import { sanityFetch } from "@/sanity/lib/live"; -import { client } from "@/sanity/lib/client"; import PaginateList from "@/components/paginate-list"; import { docCount } from "@/sanity/lib/queries"; -import { groq } from "next-sanity"; const LIMIT = 10; type Params = Promise<{ num: string }>; -export const revalidate = 60; -export async function generateStaticParams() { - const count = await client.fetch( - groq`count(*[_type == "guest" && defined(slug.current)])`, - ); - const perPage = LIMIT; - const pages = Math.ceil(count / perPage); - return Array.from({ length: pages }, (_, i) => ({ num: String(i + 1) })); -} export default async function Page({ params }: { params: Params }) { const [count] = ( diff --git a/app/(main)/(podcast)/podcast/[slug]/page.tsx b/app/(main)/(podcast)/podcast/[slug]/page.tsx index 058757e4..c20c0824 100644 --- a/app/(main)/(podcast)/podcast/[slug]/page.tsx +++ b/app/(main)/(podcast)/podcast/[slug]/page.tsx @@ -2,15 +2,12 @@ import type { Metadata, ResolvingMetadata } from "next"; import { notFound } from "next/navigation"; import type { PodcastQueryResult } from "@/sanity/types"; import { sanityFetch } from "@/sanity/lib/live"; -import { client } from "@/sanity/lib/client"; import { podcastQuery } from "@/sanity/lib/queries"; import { resolveOpenGraphImage } from "@/sanity/lib/utils"; import Podcast from "../Podcast"; -import { groq } from "next-sanity"; type Params = Promise<{ slug: string }>; -export const revalidate = 3600; export async function generateMetadata( { params }: { params: Params }, @@ -41,12 +38,6 @@ export async function generateMetadata( } satisfies Metadata; } -export async function generateStaticParams() { - const slugs = await client.fetch( - groq`*[_type == "podcast" && defined(slug.current)].slug.current`, - ); - return slugs.map((slug) => ({ slug })); -} export default async function PodcastPage({ params }: { params: Params }) { const { slug } = await params; diff --git a/app/(main)/(podcast)/podcasts/page.tsx b/app/(main)/(podcast)/podcasts/page.tsx index fd03f00c..e7a638a3 100644 --- a/app/(main)/(podcast)/podcasts/page.tsx +++ b/app/(main)/(podcast)/podcasts/page.tsx @@ -16,7 +16,6 @@ import MoreHeader from "@/components/more-header"; import PodmatchBadge from "@/components/podmatch-badge"; -export const revalidate = 60; function HeroPodcast({ title, slug, diff --git a/app/(main)/(podcast)/podcasts/page/[num]/page.tsx b/app/(main)/(podcast)/podcasts/page/[num]/page.tsx index 605ab84e..af40e9d8 100644 --- a/app/(main)/(podcast)/podcasts/page/[num]/page.tsx +++ b/app/(main)/(podcast)/podcasts/page/[num]/page.tsx @@ -1,26 +1,15 @@ import MoreContent from "@/components/more-content"; import type { DocCountResult } from "@/sanity/types"; import { sanityFetch } from "@/sanity/lib/live"; -import { client } from "@/sanity/lib/client"; import PaginateList from "@/components/paginate-list"; import { docCount } from "@/sanity/lib/queries"; -import { groq } from "next-sanity"; const LIMIT = 10; type Params = Promise<{ num: string }>; -export const revalidate = 60; -export async function generateStaticParams() { - const count = await client.fetch( - groq`count(*[_type == "podcast" && defined(slug.current)])`, - ); - const perPage = LIMIT; - const pages = Math.ceil(count / perPage); - return Array.from({ length: pages }, (_, i) => ({ num: String(i + 1) })); -} export default async function Page({ params }: { params: Params }) { const [count] = ( diff --git a/app/(main)/(post)/blog/page.tsx b/app/(main)/(post)/blog/page.tsx index 0e284d05..b980d579 100644 --- a/app/(main)/(post)/blog/page.tsx +++ b/app/(main)/(post)/blog/page.tsx @@ -15,7 +15,6 @@ import { Separator } from "@/components/ui/separator"; import MoreHeader from "@/components/more-header"; -export const revalidate = 60; function HeroPost({ title, slug, diff --git a/app/(main)/(post)/blog/page/[num]/page.tsx b/app/(main)/(post)/blog/page/[num]/page.tsx index 0be78de0..d92cd61b 100644 --- a/app/(main)/(post)/blog/page/[num]/page.tsx +++ b/app/(main)/(post)/blog/page/[num]/page.tsx @@ -1,26 +1,15 @@ import MoreContent from "@/components/more-content"; import type { DocCountResult } from "@/sanity/types"; import { sanityFetch } from "@/sanity/lib/live"; -import { client } from "@/sanity/lib/client"; import PaginateList from "@/components/paginate-list"; import { docCount } from "@/sanity/lib/queries"; -import { groq } from "next-sanity"; const LIMIT = 10; type Params = Promise<{ num: string }>; -export const revalidate = 60; -export async function generateStaticParams() { - const count = await client.fetch( - groq`count(*[_type == "post" && defined(slug.current)])`, - ); - const perPage = LIMIT; - const pages = Math.ceil(count / perPage); - return Array.from({ length: pages }, (_, i) => ({ num: String(i + 1) })); -} export default async function Page({ params }: { params: Params }) { const [count] = ( diff --git a/app/(main)/(post)/post/[slug]/page.tsx b/app/(main)/(post)/post/[slug]/page.tsx index b735009e..4cd400af 100644 --- a/app/(main)/(post)/post/[slug]/page.tsx +++ b/app/(main)/(post)/post/[slug]/page.tsx @@ -1,5 +1,5 @@ import type { Metadata, ResolvingMetadata } from "next"; -import { groq, type PortableTextBlock } from "next-sanity"; +import { type PortableTextBlock } from "next-sanity"; import { notFound } from "next/navigation"; import { Suspense } from "react"; @@ -10,7 +10,6 @@ import PortableText from "@/components/portable-text"; import type { PostQueryResult } from "@/sanity/types"; import { sanityFetch } from "@/sanity/lib/live"; -import { client } from "@/sanity/lib/client"; import { postQuery } from "@/sanity/lib/queries"; import { resolveOpenGraphImage } from "@/sanity/lib/utils"; import CoverMedia from "@/components/cover-media"; @@ -20,7 +19,6 @@ import SponsorCard from "@/components/sponsor-card"; type Params = Promise<{ slug: string }>; -export const revalidate = 3600; export async function generateMetadata( { params }: { params: Params }, @@ -51,12 +49,6 @@ export async function generateMetadata( } satisfies Metadata; } -export async function generateStaticParams() { - const slugs = await client.fetch( - groq`*[_type == "post" && defined(slug.current)].slug.current`, - ); - return slugs.map((slug) => ({ slug })); -} export default async function PostPage({ params }: { params: Params }) { const { slug } = await params; diff --git a/app/(main)/(sponsor)/sponsor/[slug]/page.tsx b/app/(main)/(sponsor)/sponsor/[slug]/page.tsx index 383792aa..6b616a16 100644 --- a/app/(main)/(sponsor)/sponsor/[slug]/page.tsx +++ b/app/(main)/(sponsor)/sponsor/[slug]/page.tsx @@ -1,5 +1,5 @@ import type { Metadata, ResolvingMetadata } from "next"; -import { groq, type PortableTextBlock } from "next-sanity"; +import { type PortableTextBlock } from "next-sanity"; import { notFound } from "next/navigation"; import PortableText from "@/components/portable-text"; @@ -9,7 +9,6 @@ import type { SponsorQueryWithRelatedResult, } from "@/sanity/types"; import { sanityFetch } from "@/sanity/lib/live"; -import { client } from "@/sanity/lib/client"; import { sponsorQuery, sponsorQueryWithRelated } from "@/sanity/lib/queries"; import { resolveOpenGraphImage } from "@/sanity/lib/utils"; import CoverMedia from "@/components/cover-media"; @@ -20,7 +19,6 @@ import UserRelated from "@/components/user-related"; type Params = Promise<{ slug: string }>; -export const revalidate = 3600; export async function generateMetadata( { params }: { params: Params }, @@ -47,12 +45,6 @@ export async function generateMetadata( } satisfies Metadata; } -export async function generateStaticParams() { - const slugs = await client.fetch( - groq`*[_type == "sponsor" && defined(slug.current)].slug.current`, - ); - return slugs.map((slug) => ({ slug })); -} export default async function SponsorPage({ params }: { params: Params }) { const { slug } = await params; diff --git a/app/(main)/(sponsor)/sponsors/page/[num]/page.tsx b/app/(main)/(sponsor)/sponsors/page/[num]/page.tsx index af3d45c1..1e5d0ea8 100644 --- a/app/(main)/(sponsor)/sponsors/page/[num]/page.tsx +++ b/app/(main)/(sponsor)/sponsors/page/[num]/page.tsx @@ -4,26 +4,15 @@ import Link from "next/link"; import MoreContent from "@/components/more-content"; import type { DocCountResult } from "@/sanity/types"; import { sanityFetch } from "@/sanity/lib/live"; -import { client } from "@/sanity/lib/client"; import PaginateList from "@/components/paginate-list"; import { docCount } from "@/sanity/lib/queries"; -import { groq } from "next-sanity"; const LIMIT = 10; type Params = Promise<{ num: string }>; -export const revalidate = 60; -export async function generateStaticParams() { - const count = await client.fetch( - groq`count(*[_type == "sponsor" && defined(slug.current)])`, - ); - const perPage = LIMIT; - const pages = Math.ceil(count / perPage); - return Array.from({ length: pages }, (_, i) => ({ num: String(i + 1) })); -} export default async function Page({ params }: { params: Params }) { const [count] = ( diff --git a/app/(main)/(top-level-pages)/[slug]/page.tsx b/app/(main)/(top-level-pages)/[slug]/page.tsx index e325e877..9c099fb6 100644 --- a/app/(main)/(top-level-pages)/[slug]/page.tsx +++ b/app/(main)/(top-level-pages)/[slug]/page.tsx @@ -1,12 +1,11 @@ import type { Metadata, ResolvingMetadata } from "next"; -import { groq, type PortableTextBlock } from "next-sanity"; +import { type PortableTextBlock } from "next-sanity"; import { notFound } from "next/navigation"; import PortableText from "@/components/portable-text"; import type { PageQueryResult } from "@/sanity/types"; import { sanityFetch } from "@/sanity/lib/live"; -import { client } from "@/sanity/lib/client"; import { pageQuery } from "@/sanity/lib/queries"; import { resolveOpenGraphImage } from "@/sanity/lib/utils"; @@ -15,7 +14,6 @@ type Props = { searchParams: Promise<{ [key: string]: string | string[] | undefined }>; }; -export const revalidate = 86400; export async function generateMetadata( { params, searchParams }: Props, @@ -42,12 +40,6 @@ export async function generateMetadata( } satisfies Metadata; } -export async function generateStaticParams() { - const slugs = await client.fetch( - groq`*[_type == "page" && defined(slug.current)].slug.current`, - ); - return slugs.map((slug) => ({ slug })); -} export default async function PagePage({ params, searchParams }: Props) { const { slug } = await params; diff --git a/app/(main)/(top-level-pages)/pro/page.tsx b/app/(main)/(top-level-pages)/pro/page.tsx index 6c67c04e..18606fe3 100644 --- a/app/(main)/(top-level-pages)/pro/page.tsx +++ b/app/(main)/(top-level-pages)/pro/page.tsx @@ -16,7 +16,6 @@ type Props = { searchParams: Promise<{ [key: string]: string | string[] | undefined }>; }; -export const revalidate = 86400; export async function generateMetadata( { params, searchParams }: Props, diff --git a/app/(main)/(top-level-pages)/sponsorships/page.tsx b/app/(main)/(top-level-pages)/sponsorships/page.tsx index d0aadf63..31e9e1c8 100644 --- a/app/(main)/(top-level-pages)/sponsorships/page.tsx +++ b/app/(main)/(top-level-pages)/sponsorships/page.tsx @@ -7,7 +7,6 @@ import { resolveOpenGraphImage } from "@/sanity/lib/utils"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { SponsorshipForm } from "./sponsorship-form"; -export const revalidate = 86400; const sponsorshipTiers = [ { name: "Dedicated Video", diff --git a/app/(main)/page.tsx b/app/(main)/page.tsx index 21da33b4..101bcdf9 100644 --- a/app/(main)/page.tsx +++ b/app/(main)/page.tsx @@ -8,7 +8,6 @@ import { homePageQuery } from "@/sanity/lib/queries"; import Link from "next/link"; import CoverMedia from "@/components/cover-media"; -export const revalidate = 60; export default async function HomePage() { const [homePageFetch] = await Promise.all([ diff --git a/app/api/webhooks/sanity-revalidate/route.ts b/app/api/webhooks/sanity-revalidate/route.ts index 0418a99c..fe403060 100644 --- a/app/api/webhooks/sanity-revalidate/route.ts +++ b/app/api/webhooks/sanity-revalidate/route.ts @@ -23,10 +23,32 @@ export async function POST(request: NextRequest) { ); } - // Revalidate all sanity-tagged caches (the "heavy hammer" approach) - // This is a backup for when no visitors are active to trigger SanityLive revalidation - // Next.js 16 requires a second argument — { expire: 0 } for immediate invalidation - revalidateTag("sanity", { expire: 0 }); + // With defineLive + , content pages get real-time updates + // without ISR revalidation. We only keep revalidateTag("sanity") as a + // fallback for when no active visitors are triggering live updates. + // + // IMPORTANT: Skip pipeline/internal document types that don't have + // public-facing pages. These fire frequently (every cron run) and + // were the primary cause of ISR write exhaustion. + const SKIP_TYPES = new Set([ + "automatedVideo", + "contentIdea", + "sponsorLead", + "pipeline_config", + "content_config", + ]); + + if (SKIP_TYPES.has(body._type)) { + return NextResponse.json({ + skipped: true, + type: body._type, + reason: "Internal document type — no revalidation needed", + }); + } + + // For public content types, revalidate the sanity tag as a fallback. + // This only affects pages that still use Next.js cache tags (e.g., sitemap). + revalidateTag("sanity"); return NextResponse.json({ revalidated: true, diff --git a/app/sitemap.ts b/app/sitemap.ts index dec59d51..56b8f069 100644 --- a/app/sitemap.ts +++ b/app/sitemap.ts @@ -4,7 +4,6 @@ import { sanityFetch } from "@/sanity/lib/live"; import type { SitemapQueryResult } from "@/sanity/types"; import { ContentType } from "@/lib/types"; -export const revalidate = 3600; export default async function sitemap(): Promise { const productionDomain = process.env.VERCEL_PROJECT_PRODUCTION_URL; diff --git a/lib/services/remotion.ts b/lib/services/remotion.ts index df3298f3..9b2665d4 100644 --- a/lib/services/remotion.ts +++ b/lib/services/remotion.ts @@ -48,7 +48,13 @@ export interface RenderInput { bRollKeywords?: string[]; sceneNumber?: number; durationEstimate?: number; + sceneType?: string; + code?: { snippet: string; language: string; highlightLines?: number[] }; + list?: { items: string[]; icon?: string }; + comparison?: { leftLabel: string; rightLabel: string; rows: { left: string; right: string }[] }; + mockup?: { deviceType: string; screenContent: string }; infographicUrl?: string; + wordTimestamps?: Array<{ text: string; startMs: number; endMs: number }>; }>; cta: string; }; @@ -112,13 +118,8 @@ function mapInputProps(input: RenderInput): Record { audioDurationInSeconds: input.audioDurationSeconds, hook: input.script.hook, scenes: input.script.scenes.map((s, i) => ({ - narration: s.narration, - visualDescription: s.visualDescription, - bRollKeywords: s.bRollKeywords, - sceneNumber: s.sceneNumber, - durationEstimate: s.durationEstimate, + ...s, bRollUrl: input.bRollUrls[i], - ...(s.infographicUrl ? { infographicUrl: s.infographicUrl } : {}), })), cta: input.script.cta, sponsor: input.sponsor,