IANews
GuidesPublishing

NextJS Direct Publishing

Publish articles directly to a Next.js site via PostgreSQL insert and ISR revalidation webhook.

NextJS Direct Publishing

Publish articles directly to a Next.js application backed by PostgreSQL -- no CMS middleware required. IANews inserts rows into a public_posts table and triggers a revalidation webhook to rebuild your static pages via on-demand ISR.

How it works

  1. IANews inserts the article into the public_posts table in your PostgreSQL database
  2. IANews fires a revalidation webhook to your Next.js /api/revalidate endpoint
  3. Next.js regenerates the affected static page via on-demand ISR
  4. Your readers see the updated content within seconds

This is the fastest publishing path in IANews -- zero API overhead, direct database writes.

Set up NextJS Direct

Configure the database connection

IANews uses the same PostgreSQL instance for NextJS Direct publishing. Navigate to Sites -- select your site -- Connections -- NextJS Direct. Enter your PostgreSQL connection string:

postgresql://user:password@host:port/dbname

IANews creates or updates rows in the public_posts table using an upsert on (site_id, slug), so re-publishing the same article updates it in place.

Test the connection

Click Test Connection. IANews verifies that the public_posts table exists and is writable with the provided credentials.

Set the revalidation webhook URL

Enter the URL of your Next.js revalidation API route:

  • Webhook URL -- e.g. https://yoursite.com/api/revalidate
  • Webhook Secret -- A shared secret for HMAC-SHA256 signature verification

Save the connection

Click Save. NextJS Direct is now active.

Store your database credentials securely. Never expose the PostgreSQL connection string in frontend code or client-side environment variables. Use server-side environment variables only.

Revalidation webhook

After inserting a new post, IANews sends a POST request to your webhook URL with a JSON body containing the post slug and the path to revalidate (e.g., /en/my-article-slug). The secret is included in the payload for verification.

Create the revalidation API route

Implement this handler in your Next.js application at app/api/revalidate/route.ts:

import crypto from 'crypto';
import { revalidatePath } from 'next/cache';
import { NextRequest } from 'next/server';
 
export async function POST(request: NextRequest) {
  const body = await request.text();
  const payload = JSON.parse(body);
 
  // Verify the shared secret
  const secret = process.env.IANEWS_REVALIDATE_SECRET;
  if (payload.secret !== secret) {
    return new Response('Unauthorized', { status: 401 });
  }
 
  // Revalidate the article page
  const path = payload.path; // e.g. "/en/ai-adoption-newsrooms"
  revalidatePath(path);
 
  return Response.json({ revalidated: true, path });
}

For additional security, you can also verify an HMAC-SHA256 signature. See the Webhooks guide for the full signature verification pattern.

Reading posts in your Next.js site

Query the public_posts table from your Next.js server components:

import { Pool } from 'pg';
 
const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
});
 
export async function getPublishedPosts(siteId: string) {
  const { rows } = await pool.query(
    `SELECT slug, title, content_html, intro, image_url, image_alt,
            seo_title, seo_description, published_at
     FROM public_posts
     WHERE site_id = $1 AND status = 'published'
     ORDER BY published_at DESC`,
    [siteId]
  );
  return rows;
}
 
export async function getPostBySlug(siteId: string, slug: string) {
  const { rows } = await pool.query(
    `SELECT * FROM public_posts
     WHERE site_id = $1 AND slug = $2 AND status = 'published'`,
    [siteId, slug]
  );
  return rows[0] ?? null;
}

Database schema

The public_posts table contains the following columns:

ColumnTypeDescription
site_idTEXTSite identifier
article_idTEXTIANews article ID
slugTEXTURL-friendly slug (unique per site)
titleTEXTArticle title
content_htmlTEXTFull HTML content
introTEXTArticle introduction / excerpt
langTEXTLanguage code (e.g., en, fr)
seo_titleTEXTSEO meta title
seo_descriptionTEXTSEO meta description
image_urlTEXTFeatured image URL
published_atTIMESTAMPTZPublication timestamp
statusTEXTpublished or draft

Automatic error recovery

The NextJS Direct adapter includes built-in automatic error recovery. If several consecutive database inserts fail, publishing is temporarily paused. Requests are queued and retried automatically once the connection recovers. No manual intervention is needed.

What's next?

  • WordPress -- Publish to WordPress if you prefer a traditional CMS
  • Ghost CMS -- Publish to Ghost for newsletter-driven distribution
  • Webhooks -- Set up event notifications for custom integrations