Files
chat_web_app/llm-fe/scripts/pingIndexNow.js
T
westfarnandCursor f9d39f6589
Unit Tests / test (pull_request) Successful in 37s
Give public pages crawler-ready HTML and production analytics.
Crawlers were reading one shared shell, so titles, descriptions, links, and markup were missing or the same on every URL. HeyCatch and Google Analytics load only on the production site and the iOS and Android apps.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-19 09:56:49 -05:00

41 lines
1.3 KiB
JavaScript

/**
* One IndexNow POST for the URLs in the sitemap. Run after the prod files are published.
*/
const fs = require('fs');
const path = require('path');
const { INDEXNOW_KEY, indexNowBody, sitemapEntries } = require('./sitemap');
async function pingIndexNow(fetchImpl = fetch, urls) {
const keyPath = path.join(__dirname, '..', 'public', `${INDEXNOW_KEY}.txt`);
const key = fs.readFileSync(keyPath, 'utf8').trim();
if (key !== INDEXNOW_KEY) {
throw new Error(`IndexNow key file does not match ${INDEXNOW_KEY}`);
}
const urlList = urls || sitemapEntries().map((entry) => entry.loc);
const body = indexNowBody(key, urlList);
const response = await fetchImpl('https://api.indexnow.org/indexnow', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
const text = await response.text();
if (response.status !== 200 && response.status !== 202) {
throw new Error(`IndexNow ${response.status}: ${text}`);
}
return { status: response.status, body };
}
async function main() {
const result = await pingIndexNow();
process.stdout.write(`IndexNow ${result.status}\n`);
}
module.exports = { pingIndexNow };
if (require.main === module) {
main().catch((error) => {
process.stderr.write(`${error.message}\n`);
process.exit(1);
});
}