Dynamic Blog Studio Puzzle #44

Clue: Supabase Dynamic Storage + Next.js ISR
PostgreSQL Dynamic Sync Active (Zero CI/CD Redeployment)
Posts in DB: 3 Active Provider: Supabase Mock/Local Edge ISR Cache: REVALIDATED (Fresh)

Blog Articles

Media Title & Slug Status Date Actions

New Article

/blog/
Wallpaper Banner Preview
Preset Presets:
| | |

Exploring Dynamic Publishing Without Redeployment

Traditional static site generators require a full CI/CD pipeline build every time a copywriter edits a single sentence. By pairing Supabase with Next.js ISR, editorial teams achieve instant dynamic persistence without sacrificing edge CDN caching speeds.

"Publishing content should be as fast as sending a chat message, not waiting on a 5-minute container deployment."

Our blog

Article Wallpaper

Test

Next.js ISR (Incremental Static Regeneration) & On-Demand Revalidation

Instead of rebuilding the entire website on every commit, Next.js ISR serves pre-rendered static HTML from edge CDNs while Supabase mutations trigger instant background cache purges using revalidatePath and revalidateTag.

01

Admin Content Mutation

Editor updates a post in the Admin Panel and hits Save. The row is updated in Supabase PostgreSQL.

02

Database Webhook Trigger

Supabase dispatches an HTTP POST webhook to Next.js route /api/revalidate?secret=....

03

Edge Cache Invalidation

Next.js executes revalidatePath('/blog/[slug]'), clearing the stale edge CDN cache entry.

04

Zero-Rebuild Instant Delivery

The very next visitor instantly receives fresh, statically optimized HTML in under 15ms.

Interactive Cache Simulator

STATIC_HIT (Edge CDN)

Trigger simulated traffic events to observe how Next.js headers and cache tags react dynamically:

[00:00:01] INIT Next.js Edge CDN initialized. Cache key: /blog/test
[00:00:02] HIT x-nextjs-cache: HIT | age: 14s | status: 200 OK (9ms)

Next.js App Router Code Blueprint

TypeScript (App Router)
// app/blog/[slug]/page.tsx import { notFound } from 'next/navigation'; import { supabase } from '@/lib/supabaseClient'; // Time-based background revalidation fallback export const revalidate = 60; export async function generateStaticParams() { const { data: posts } = await supabase .from('blog_posts').select('slug').eq('status', 'published'); return (posts || []).map((p) => ({ slug: p.slug })); } // app/api/revalidate/route.ts (On-Demand Webhook) import { revalidatePath } from 'next/cache'; export async function POST(req: Request) { const { slug } = await req.json(); revalidatePath('/blog'); revalidatePath(`/blog/${slug}`); return Response.json({ revalidated: true, now: Date.now() }); }

Supabase PostgreSQL Schema & RLS Security

Ready-to-run DDL with table definition, slug unique index, automatic updated_at trigger, and public/admin RLS policies.

-- 1. Create Posts Table
CREATE TABLE IF NOT EXISTS public.blog_posts (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  title TEXT NOT NULL,
  slug TEXT NOT NULL UNIQUE,
  wallpaper_url TEXT NOT NULL DEFAULT '',
  excerpt TEXT NOT NULL DEFAULT '',
  content TEXT NOT NULL DEFAULT '',
  status TEXT NOT NULL CHECK (status IN ('draft', 'published')) DEFAULT 'draft',
  category TEXT NOT NULL DEFAULT 'Engineering',
  author_name TEXT NOT NULL DEFAULT 'Editorial Team',
  author_email TEXT NOT NULL DEFAULT 'admin@puzzlehub.dev',
  read_time TEXT NOT NULL DEFAULT '3 min read',
  published_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- 2. Indexes for Blazing Fast Queries
CREATE INDEX IF NOT EXISTS idx_blog_posts_slug ON public.blog_posts (slug);
CREATE INDEX IF NOT EXISTS idx_blog_posts_status_published ON public.blog_posts (status, published_at DESC);

-- 3. Automatic Updated-At Trigger
CREATE OR REPLACE FUNCTION public.handle_blog_updated_at()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = now();
  IF NEW.status = 'published' AND OLD.status = 'draft' AND NEW.published_at IS NULL THEN
    NEW.published_at = now();
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trigger_blog_posts_updated_at
  BEFORE UPDATE ON public.blog_posts
  FOR EACH ROW EXECUTE FUNCTION public.handle_blog_updated_at();

-- 4. Row Level Security (RLS)
ALTER TABLE public.blog_posts ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Public visitors can view published posts"
  ON public.blog_posts FOR SELECT
  TO anon, authenticated
  USING (status = 'published');

CREATE POLICY "Admins have full CRUD access"
  ON public.blog_posts FOR ALL
  TO authenticated
  USING (true) WITH CHECK (true);
          

Automated 8-Point Diagnostic Test Suite

Runs live client-side integration and regression assertions across Supabase CRUD, slug routing, zero-redeploy live update, and ISR revalidation.