IndexNow Setup
Overview
IndexNow is a protocol that lets websites notify search engines about new, updated, or deleted URLs in real time. Instead of waiting for crawlers, you push URLs directly to api.indexnow.org, and participating search engines (Bing, Yandex, Seznam, Naver) pick them up.
Workflow
Step 1: Generate and place the key file
Generate a random 32-character hex key:
node -e "console.log(require('crypto').randomBytes(16).toString('hex'))"
Place a .txt file named <key>.txt containing only the key string into the site's public root:
- Next.js App Router --
public/<key>.txt - Next.js Pages Router --
public/<key>.txt - Plain static site -- root directory (e.g.,
dist/orpublic/) - Vite / CRA --
public/<key>.txt - Nuxt --
public/<key>.txt
After deploy, the file must be accessible at https://<domain>/<key>.txt with a 200 response containing only the key string.
Step 2: Create the submission script
Copy scripts/submit-indexnow.mjs from this skill into the project (e.g., scripts/submit-indexnow.mjs).
If the project already has package.json, add an npm script:
"indexnow": "node scripts/submit-indexnow.mjs"
Or add a site_url and key pair inline:
"indexnow": "node scripts/submit-indexnow.mjs https://example.com abcd1234..."
Step 3: Ensure a sitemap exists
The script reads URLs from /sitemap.xml. Ensure the site generates a valid sitemap at that path. For Next.js App Router, this is typically app/sitemap.ts.
Step 4: Submit URLs
Run after every deploy or content update:
npm run indexnow
The script:
- Fetches
sitemap.xmlfrom the site - Extracts all
<loc>URLs - POSTs them to
https://api.indexnow.org/IndexNow
For non-Node projects, invoke the script directly:
node scripts/submit-indexnow.mjs https://example.com <key>
Step 5: Verify
Use Bing Webmaster Tools to confirm URLs are being received. Check the URL inspection tool for submission history.
Environment Variables
The script accepts arguments or environment variables:
| Priority | Source |
|---|---|
| 1st | CLI args: node submit-indexnow.mjs <url> <key> |
| 2nd | SITE_URL + INDEXNOW_KEY env vars |
HTTP Response Codes
| Status | Meaning |
|---|---|
| 200 | URLs submitted successfully |
| 400 | Invalid request format |
| 403 | Key not found or invalid |
| 422 | URLs don't belong to the host |
| 429 | Rate limited (spam protection) |