Skip to content

perf: implement ISR caching with tag-based revalidation#602

Merged
codercatdev merged 19 commits intodevfrom
feature/nextjs-caching-optimization
Mar 5, 2026
Merged

perf: implement ISR caching with tag-based revalidation#602
codercatdev merged 19 commits intodevfrom
feature/nextjs-caching-optimization

Conversation

@codercatdev
Copy link
Contributor

@codercatdev codercatdev commented Mar 5, 2026

⚡ Next.js Caching Optimization + Course Removal

Caching: Aligned with next-sanity defineLive Best Practices

After reading the next-sanity caching docs, we aligned with the recommended defineLive approach:

  • defineLive's sanityFetch automatically sets cache tags — opaque sanity: prefixed tags generated by the backend
  • <SanityLive /> automatically revalidates — listens to Live Content API and calls revalidateTag() when content changes
  • <SanityLive /> always renders (not behind draft mode) — required for cache revalidation

What this PR adds:

  • 13 generateStaticParams — Pre-renders all posts, podcasts, authors, guests, sponsors, pages at build time
  • 20 revalidate exports — Safety net: 60s for listings, 3600s for detail pages, 86400s for static pages
  • Backup revalidation webhook at /api/webhooks/sanity-revalidate — calls revalidateTag("sanity") for when no visitors are active
  • token.ts fix — Warns instead of throwing when SANITY_API_READ_TOKEN is missing

What we intentionally kept as-is:

  • defineLive pattern in sanity/lib/live.ts — handles caching automatically
  • <SanityLive /> always rendered in layout — triggers cache revalidation for all visitors
  • No manual cache tags on sanityFetch calls — defineLive generates them

Course Removal 🧹

Courses have been removed from navigation and are no longer active.

Deleted (13 route files):

  • app/(main)/(course)/ — all pages, lessons, RSS feeds

Cleaned up references in:

  • sanity/lib/queries.ts — removed course/lesson queries, partials, related content refs
  • lib/types.ts — removed course/lesson from ContentType enum
  • components/more-content.tsx — removed course query case
  • components/algolia-search.tsx — removed course/lesson icon cases
  • app/(main)/layout.tsx — removed courses RSS link
  • app/sitemap.ts — removed course/lesson URL generation
  • components/user-related.tsx — removed course from related content
  • sanity/schemas/custom/internalLink.ts — removed course from reference types

Kept:

  • sanity/schemas/documents/course.ts and lesson.ts — for Sanity Studio access to existing data

Setup After Merge

  1. Optional: Set SANITY_REVALIDATE_SECRET env var + Sanity webhook for backup revalidation when no visitors are active

- Create sanity/lib/fetch.ts: ISR-compatible sanityFetch with cache tags
  - Production: uses Sanity CDN + Next.js revalidate + cache tags
  - Draft mode: bypasses cache, uses token for draft content
- Update sanity/lib/live.ts: re-export new sanityFetch, keep SanityLive for drafts
- Fix sanity/lib/token.ts: warn instead of throw when token missing
- Create /api/webhooks/sanity-revalidate: on-demand cache invalidation
- Add generateStaticParams to 13 dynamic routes (posts, podcasts, courses, etc.)
- Add revalidate exports to 20 pages (60s listings, 3600s detail, 86400s static)
- Add cache tags to all sanityFetch calls across 24 files
- Conditionally render SanityLive + VisualEditing only in draft mode

Expected impact:
- TTFB: 300-800ms → 50-100ms (edge cached)
- Sanity API calls: every page view → 1 per revalidation period
- Content freshness: 60s for listings, on-demand for detail pages
@vercel
Copy link

vercel bot commented Mar 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
codingcat-dev Canceled Canceled Mar 5, 2026 4:13am

Reverts the custom sanityFetch/fetch.ts approach in favor of defineLive's
built-in caching. defineLive automatically:
- Sets cache tags (opaque sanity: prefixed tags)
- Revalidates via SanityLive component listening to Live Content API
- Integrates with ISR so all visitors see fresh content

Changes:
- Revert sanity/lib/live.ts to standard defineLive pattern
- Delete sanity/lib/fetch.ts (not needed)
- SanityLive always renders (required for cache revalidation)
- Remove manual tags from all sanityFetch calls
- Fix generateStaticParams to use client.fetch directly
- Keep revalidate exports as safety net (20 pages)
- Keep generateStaticParams for build-time pre-rendering (13 routes)
- Simplify webhook to revalidateTag("sanity") backup
Courses have been removed from navigation and are no longer active.
Route files already deleted. This commit cleans up all remaining references:

- queries.ts: remove course/lesson queries, partials, and related content refs
- types.ts: remove course/lesson from ContentType enum
- more-content.tsx: remove course query case
- algolia-search.tsx: remove course/lesson icon cases
- layout.tsx: remove courses RSS link
- sitemap.ts: remove course/lesson URL generation
- user-related.tsx: remove course from related content check
- internalLink.ts: remove course from reference types

Sanity schemas (course.ts, lesson.ts) kept for Studio access to existing data.
- pro-benefits.tsx: replace course marketing copy with generic content terms
- rss.ts: remove dead course case from typePath()
- algolia-search.tsx: remove commented-out course initialUiState
- sanity.config.ts: remove course/lesson schema imports and registrations
- Deleted: sanity/schemas/documents/course.ts, lesson.ts
@codercatdev codercatdev merged commit 4df823b into dev Mar 5, 2026
1 of 3 checks passed
@codercatdev codercatdev deleted the feature/nextjs-caching-optimization branch March 5, 2026 05:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant