Skip to content

Instantly share code, notes, and snippets.

@albertogalca
Last active October 21, 2025 08:32
Show Gist options
  • Select an option

  • Save albertogalca/99367ad09b1d47ca127f982100c66953 to your computer and use it in GitHub Desktop.

Select an option

Save albertogalca/99367ad09b1d47ca127f982100c66953 to your computer and use it in GitHub Desktop.
indexnow
// IndexNow Sitemap Submitter (Node.js 18+)
// Uses native fetch - no dependencies needed!
const { parseStringPromise } = require("xml2js");
// Configuration
const SITEMAP_URL = "YOUR_SITEMAP_URL";
const YOUR_API_KEY = "YOUR_API_KEY"; // Replace with your actual key (get this key in https://www.bing.com/indexnow/getstarted)
const HOST = "YOUR_HOST_URL";
const INDEXNOW_API = "https://api.indexnow.org/indexnow";
// Fetch sitemap
async function fetchSitemap(url) {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to fetch sitemap: ${response.status}`);
}
return await response.text();
}
// Extract URLs from sitemap XML
async function extractUrls(xmlContent) {
const result = await parseStringPromise(xmlContent);
const urls = result.urlset.url.map((entry) => entry.loc[0]);
return urls;
}
// Submit URLs to IndexNow
async function submitToIndexNow(urls, apiKey, host) {
const payload = {
host: host,
key: apiKey,
urlList: urls,
};
console.log("\nSubmitting payload:");
console.log(JSON.stringify(payload, null, 2));
console.log("\n");
const response = await fetch(INDEXNOW_API, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
return {
status: response.status,
statusText: response.statusText,
body: await response.text(),
};
}
// Main execution
async function main() {
try {
console.log("πŸ” Fetching sitemap from:", SITEMAP_URL);
const xmlContent = await fetchSitemap(SITEMAP_URL);
console.log("πŸ“ Parsing sitemap...");
const urls = await extractUrls(xmlContent);
console.log(`\nβœ… Found ${urls.length} URLs:`);
urls.forEach((url, index) => console.log(` ${index + 1}. ${url}`));
if (YOUR_API_KEY === "YOUR_API_KEY_HERE") {
console.log(
"\n⚠️ Please replace YOUR_API_KEY_HERE with your actual IndexNow API key!"
);
console.log("Generate one at: https://www.bing.com/indexnow/getstarted");
return;
}
console.log("\nπŸš€ Submitting to IndexNow...");
const result = await submitToIndexNow(urls, YOUR_API_KEY, HOST);
console.log("\nπŸ“Š Response:");
console.log(` Status: ${result.status} ${result.statusText}`);
if (result.status === 200) {
console.log(" βœ… Success! URLs submitted to IndexNow.");
console.log(" Search engines (Bing, Yandex, etc.) have been notified.");
} else if (result.status === 202) {
console.log(" βœ… Accepted! URLs will be processed.");
} else if (result.status === 403) {
console.log(" ❌ Forbidden: Invalid API key or key file not found.");
console.log(" Make sure your key file is hosted at:");
console.log(` https://${HOST}/${YOUR_API_KEY}.txt`);
} else if (result.status === 422) {
console.log(" ❌ Invalid request format.");
console.log(" Response:", result.body);
} else if (result.status === 429) {
console.log(" ⚠️ Too many requests. Please wait and try again later.");
} else {
console.log(" Response body:", result.body);
}
} catch (error) {
console.error("\n❌ Error:", error.message);
}
}
// Run it
main();
/*
SETUP & USAGE:
1. Install xml2js: npm install xml2js
2. Get your API key from: https://www.bing.com/indexnow/getstarted
3. Download the key file and upload it to your site root: https://{YOUR_HOST_URL}/{key}.txt
4. Replace YOUR_API_KEY_HERE above with your actual key
5. Run: node indexnow.js
Node.js 18+ required (for native fetch support)
If using older Node, install node-fetch: npm install node-fetch
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment