INTERMEDIATE · NEXT.JS
IndexNow in Next.js App Router Implementation
Implementing IndexNow in a Next.js application involves hosting the key file, creating a submission utility, and triggering submissions after content changes. This guide covers the complete implementation for Next.js App Router (13+).
Step 1: Host the Key File
Place your key file in the /public directory Next.js serves everything in /public at the root path.
# File location in your project:
public/d47a82bc1e9f4a3b8c2d5e6f7a8b9c0d.txt
# Accessible at:
https://yourdomain.com/d47a82bc1e9f4a3b8c2d5e6f7a8b9c0d.txt
# File contents (exactly):
d47a82bc1e9f4a3b8c2d5e6f7a8b9c0d
Note: This site itself uses this exact method. The key file at public/68981b2718faa42e6438cc8adda45fa2.txt is already in the project.
Step 2: Create a Submission Utility
// lib/indexnow.ts
export async function
submitToIndexNow(urls: string | string[]): Promise<number> {
const urlList = Array.isArray(urls) ? urls : [urls];
const response = await fetch('https://api.indexnow.org/indexnow', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
host: process.env.NEXT_PUBLIC_DOMAIN ?? 'yourdomain.com',
key: process.env.INDEXNOW_KEY!,
urlList,
}),
});
return response.status;
}
Environment variables: Add
INDEXNOW_KEY=your-key-here and NEXT_PUBLIC_DOMAIN=yourdomain.com to your .env.local file. Never commit your key to version control.Step 3: Trigger Submission After Content Changes
Option A: Server Action (on form submit / revalidation)
// app/actions/publish.ts
'use server';
import { revalidatePath } from 'next/cache';
import { submitToIndexNow } from '@/lib/indexnow';
export async function publishPost(slug: string) {
// ... save to database ...
revalidatePath(`/blog/${slug}`);
await submitToIndexNow(`https://yourdomain.com/blog/${slug}`);
}
Option B: CMS Webhook Handler
// app/api/cms-webhook/route.ts
import { submitToIndexNow } from '@/lib/indexnow';
export async function POST(req: Request) {
const { slug, type } = await req.json();
const url = `https://yourdomain.com/${type}/${slug}`;
await submitToIndexNow(url);
return Response.json({ ok: true });
}
Dynamic Sitemap for Bulk Submission on Deploy
For initial site launches or full re-submissions, extract all URLs from your sitemap and submit them in bulk:
// scripts/bulk-submit.ts (run as npm script)
import { submitToIndexNow } from '../lib/indexnow';
const urls = [/* your URL list */];
// Split into batches of 10,000
for (let i = 0; i < urls.length; i += 10000) {
await submitToIndexNow(urls.slice(i, i + 10000));
}