Tiny, zero-dependency IndexNow client for Node.js. Notify Bing, Yandex, Seznam, and Naver when your content changes — from a CMS webhook, a sitemap generator, or your CI pipeline.
npm install indexnow-notify
IndexNow is the standard way to push URL changes to non-Google search engines, but no maintained npm package exists for it. This is a 50-line, dependency-free client with sensible defaults, host filtering, batching, and "fire-and-forget" semantics (it never throws).
import { IndexNowClient } from "indexnow-notify";
const client = new IndexNowClient({
host: "www.example.com",
key: process.env.INDEXNOW_KEY!,
});
const result = await client.submit([
"https://www.example.com/blog/new-post",
"https://www.example.com/blog/updated-post",
]);
console.log(result);
// { submitted: 2, skipped: false, status: 200 }import { submitToIndexNow } from "indexnow-notify";
// reads INDEXNOW_HOST + INDEXNOW_KEY from env
await submitToIndexNow(["https://www.example.com/page"]);// app/api/revalidated/route.ts
import { submitToIndexNow } from "indexnow-notify";
export async function POST(req: Request) {
const { urls } = await req.json();
// fire-and-forget — IndexNow client never throws
submitToIndexNow(urls).then(console.log);
return Response.json({ ok: true });
}# install once, then:
npx indexnow-notify --host example.com --key abc https://example.com/foo https://example.com/bar
# from a file
npx indexnow-notify --host example.com --key abc --file urls.txt
# from stdin
echo "https://example.com/foo" | npx indexnow-notify --host example.com --key abc- Generate a key (any 8–128 alphanumeric chars).
- Host it as a plain text file at
https://yourhost/{key}.txtwhose contents are the key itself. - Pass
hostandkeyto the client. Done.
Submissions are forwarded by the IndexNow API to all participating engines.
| Option | Default | Description |
|---|---|---|
host |
— | Hostname (required) |
key |
— | IndexNow key (required) |
keyLocation |
https://{host}/{key}.txt |
Public URL of the key file |
endpoint |
https://api.indexnow.org/indexnow |
Override (e.g. Bing's endpoint) |
fetch |
globalThis.fetch |
Inject a custom fetch (tests, polyfills) |
type IndexNowResult = {
submitted: number;
skipped: boolean;
reason?: string;
status?: number;
};The client never throws. Inspect result.skipped and result.reason to decide whether to log/alert.
MIT