How to Integrate IndexNow API with Node.js — Step-by-Step Guide for Instant SEO Indexing
TL;DR
What is IndexNow?
IndexNow is this cool open protocol that lets websites instantly tell search engines (like Bing, Yandex, and others) when you add, update, or delete stuff. It's a pretty neat way to help search engines keep their indexes current. (In-Depth Guide to How Google Search Works)
Prerequisites
You'll need a Node.js project, and make sure you've got
axios
installed.You gotta have access to your website’s root directory, 'cause that's where we'll put the key.
And of course, a public-facing domain (like
https://www.example.com
).
Step 1: Generate Your IndexNow API Key
So, you need an api key to prove your domain is yours.
- Go ahead and generate a key. The official docs say it should be a UTF-8 key, and while they don't specify a length, a common practice is to use a 32-character key. (Generate Random UTF8) You can use an online generator, or if you're feeling code-y, use this Node.js snippet:
const crypto = require('crypto');
const key = crypto.randomBytes(16).toString('hex');
console.log("Generated IndexNow Key:", key);
Example Key:4262631fe57245bd9bd1cef01d1c3fa4
Step 2: Host the API Key on Your Site
Now, you gotta create a .txt
file. Name it using your key and stick it in the root of your website.
Filename:
4262631fe57245bd9bd1cef01d1c3fa4.txt
Content inside file: Just the key itself (
4262631fe57245bd9bd1cef01d1c3fa4
)URL:
https://www.example.com/4262631fe57245bd9bd1cef01d1c3fa4.txt
Quick Note: If you decide to put the key file somewhere else, that's fine, but you'll need to tell IndexNow where it is using the keyLocation
parameter when you submit URLs.
Step 3: Submit URLs via Node.js Script
File Structure
Here's a simple way to organize your project:
├── config.js
├── indexnow.js <-- This is where the IndexNow magic happens
└── submit.js <-- This is for running and testing the submission
config.js
Let's set up some basic config:
module.exports = {
indexNow: {
agent: 'my-custom-agent',
source: 'my-website-source'
}
};
indexnow.js
— Core Logic
This is the main part of the script:
const crypto = require('crypto');
const axios = require('axios');
const config = require('./config');
function getDomainFromUrl(url) {
try {
const parsedUrl = new URL(url);
return parsedUrl.hostname;
} catch (e) {
console.error('Invalid URL:', url);
return null;
}
}
async function submitToIndexNow(siteUrl, indexNowKey, urlList) {
try {
// Basic checks to make sure we have everything
if (!siteUrl || !indexNowKey || !urlList || !Array.isArray(urlList)) {
throw new Error('Missing required parameters');
}
// If there are no URLs, we can just skip it
if (urlList.length === 0) {
return { status: 'skipped', message: 'No URLs to submit' };
}
// Make sure the URLs are absolute
urlList = urlList.map((url) => siteUrl.replace(/\/$/, '') + "/" + url);
const siteDomain = getDomainFromUrl(siteUrl);
if (!siteDomain) throw new Error('Invalid site URL');
const data = {
host: siteDomain,
key: indexNowKey,
// Construct the keyLocation assuming it's in the root
keyLocation: `${siteUrl.replace(/\/$/, '')}/${indexNowKey}.txt`,
urlList: urlList
};
const headers = {
'Content-Type': 'application/json',
// Creating a user-agent, just for good measure
'User-Agent': `${config.indexNow.agent}/${crypto.createHash('md5').update(siteUrl).digest('hex')}`,
'X-Source-Info': `https://${config.indexNow.source}/1.0/`
};
// Sending the request to the IndexNow API
const response = await axios.post('https://api.indexnow.org/indexnow', data, { headers });
return {
status: 'success',
statusCode: response.status,
message: `Successfully submitted ${urlList.length} URLs`
};
} catch (error) {
// Handling potential errors during the submission
const errorMessage = error.response ?
`HTTP ${error.response.status}: ${error.response.statusText}` : error.message;
return {
status: 'error',
error: errorMessage,
message: 'Failed to submit URLs'
};
}
}
module.exports = {
submitToIndexNow,
getDomainFromUrl
};
submit.js
— Run the Submission
This is the file you'll run to actually send the URLs.
const { submitToIndexNow } = require('./indexnow');
// Your API key and the URLs you want to submit
const apiKey = '4262631fe57245bd9bd1cef01d1c3fa4';
const urls = [
'blog/passwordless-authentication-guide',
'blog/resistant-cryptography-migration'
];
const siteUrl = 'https://www.example.com';
// Calling the function to submit
submitToIndexNow(siteUrl, apiKey, urls)
.then(result => {
console.log('📬 Submission Result:', result);
})
.catch(err => {
console.error('❌ Unexpected error:', err.message);
});
Step 4: Verify Submission in Bing Webmaster Tools
After you've run the script, you can check if everything went through okay.
Head over to https://www.bing.com/webmasters/indexnow
If you haven't already, add and verify your domain.
You can use the URL inspection tool there to see the submission status.
References
API Endpoint