-
-
- Submit Updated Articles to Bing and Yandex with IndexNow in Joomla
- Add Published and Modified Date Meta Tags to Joomla
- Add Open Graph and Twitter Card Tags to Joomla
- Auto-Generate Meta Descriptions from Article Text in Joomla
- Add Noindex to Specific Pages in Joomla
- Verify Your Joomla Site with Google Search Console
-
- Add a View as Markdown Link to Joomla Articles
- Display the Last Modified Date in Joomla Articles
- Embed Iframes in Joomla
- Automatically Link Twitter (X) @mentions in Joomla Articles
- Open External Links in a New Tab in Joomla
- Display Estimated Reading Time in Joomla Articles
- Replace Old URLs in Joomla
- Search and Replace in Joomla
-
- Add a Footer Line to the Joomla Administrator
- Show a Staging Banner in the Joomla Administrator
- Remove the "All" Option from Admin List Limits in Joomla
- Add a Cookie Consent Banner to Joomla
- Make the Administrator Navigation Sticky in Joomla
- Add Google Fonts to Joomla
- Add a Facebook Messenger Chat Button to Joomla
- Add a Reading Progress Bar to Joomla
- Add a Custom Scrollbar to Joomla
- Show Confetti on a Thank You Page in Joomla
- Add Smooth Scrolling to Joomla
- Add a Back to Top Button in Joomla
- Add a WhatsApp Chat Button in Joomla
-
- Protect the Administrator with a Secret URL Key in Joomla
- Show a Welcome Message on First Login in Joomla
- Log Out Idle Administrators in Joomla
- Assign New Users to a Different User Group Automatically in Joomla
- Redirect Visitors by Country in Joomla
- Redirect Users After Login by User Group in Joomla
- Block User Registration with Certain Usernames in Joomla
- Block User Registration by Country in Joomla
- Block User Registration by Email Address in Joomla
- Block User Registration by IP Address in Joomla
- Remove the Forgot Password and Username Links in Joomla
- Remove the Generator Meta Tag in Joomla
- Let Users Log In with Their Email Address in Joomla
- Block Traffic by Country in Joomla
- Block Bot Traffic in Joomla
- Block Traffic by IP Address in Joomla
Submit Updated Articles to Bing and Yandex with IndexNow in Joomla
Send every new and updated Joomla article to Bing, Yandex and other search engines through IndexNow the moment you save it, using one PHP snippet.
You fix a price in an article, or publish a new one, and Microsoft Bing doesn't know until its crawler comes back to your site. That can take days. Bing's index reaches further than Bing itself: it powers Microsoft Copilot, and ChatGPT search is widely reported to draw on it too.
IndexNow lets you tell Bing right away. You send the address of the page that changed, and Bing passes it on to Yandex and the other search engines that use IndexNow, like Seznam and Naver. You can send every article you save or publish in the Joomla administrator to IndexNow with one PHP snippet in Code Snippets.
Create your IndexNow key
IndexNow checks that the site is yours with a key: a text file on your site that holds the same key the snippet sends.
- Open Bing's IndexNow page and generate a key. Any 8 to 128 letters, numbers and dashes work too.
- Create a text file named after the key, like
a1b2c3d4e5f6a7b8.txt, that holds only the key. - Upload the file to your Joomla root folder, the one with
configuration.phpin it, with your host's file manager or FTP. - Open
https://www.example.com/a1b2c3d4e5f6a7b8.txtin your browser, with your own domain and key.
The browser should show the key and nothing else.
The PHP snippet code
The snippet waits for 2 things in the Joomla administrator: saving an article, and publishing articles from the Articles list. It builds each article's address the same way your site's menus do, sends it to Bing's IndexNow address, and shows Bing's answer at the top of the page.
use Joomla\CMS\Factory;
use Joomla\CMS\Http\HttpFactory;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;
use Joomla\Component\Content\Site\Helper\RouteHelper;
use Joomla\Database\DatabaseInterface;
// Your IndexNow key. Your Joomla root folder needs a text file named after
// the key, like your-indexnow-key.txt, that holds only the key.
$key = 'your-indexnow-key';
// Do not edit below.
$app = Factory::getApplication();
$ping = function (array $ids) use ($app, $key) {
// Only published, public articles whose publish date has passed.
// Search engines can't open the rest.
$db = Factory::getContainer()->get(DatabaseInterface::class);
$now = Factory::getDate()->toSql();
$query = $db->createQuery()
->select($db->quoteName(['id', 'alias', 'catid', 'language']))
->from($db->quoteName('#__content'))
->whereIn($db->quoteName('id'), $ids)
->where($db->quoteName('state') . ' = 1')
->where($db->quoteName('access') . ' = 1')
->where('(' . $db->quoteName('publish_up') . ' IS NULL OR '
. $db->quoteName('publish_up') . ' <= :now)')
->bind(':now', $now);
$urls = [];
foreach ($db->setQuery($query)->loadObjectList() as $article)
{
$route = RouteHelper::getArticleRoute(
$article->id . ':' . $article->alias,
$article->catid,
$article->language
);
$urls[] = Route::link('site', $route, false, Route::TLS_IGNORE, true);
}
if (!$urls)
{
return;
}
$data = json_encode([
'host' => Uri::getInstance()->getHost(),
'key' => $key,
'keyLocation' => Uri::root() . $key . '.txt',
'urlList' => $urls,
]);
// A slow or failed request must never block saving, so wait 5 seconds
// at most and catch every error.
try
{
$result = HttpFactory::getHttp()->post(
'https://www.bing.com/indexnow',
$data,
['Content-Type' => 'application/json; charset=utf-8'],
5
)->getStatusCode();
}
catch (\Throwable $e)
{
$result = $e->getMessage();
}
// 200 means Bing accepted the key. 202 means it hasn't checked it yet.
if ($result === 200 || $result === 202)
{
$app->enqueueMessage(
'Sent to IndexNow (' . $result . '): ' . implode(', ', $urls)
);
return;
}
$app->enqueueMessage('IndexNow failed: ' . $result, 'warning');
};
// Saving an article
$app->registerEvent('onContentAfterSave', function ($event) use ($ping) {
if ($event->getContext() === 'com_content.article')
{
$ping([$event->getItem()->id]);
}
});
// Publishing articles from the Articles list
$app->registerEvent('onContentChangeState', function ($event) use ($ping) {
if ($event->getContext() === 'com_content.article' && $event->getValue() === 1)
{
$ping($event->getPks());
}
});
Replace your-indexnow-key with your key.
The snippet skips unpublished articles, articles that aren't Public and articles with a future publish date, because search engines can't open them yet. Publish several articles from the list at once and they go out in one request. If Bing doesn't answer within 5 seconds, or the request fails, the article still saves and you see a warning instead.
How to add this snippet
- Install Code Snippets if it isn't installed already.
- Log into your Joomla backend.
- Go to Components → Tassos Code Snippets.
- Click New.
- Enter a title, for example IndexNow.
- Set Code Type to PHP.
- Set Insertion Method to Auto-Insert Locations.
- Set Location to Admin Page Load.
- Paste the code above into the editor.
- Click Save & Close.
Admin locations are part of Code Snippets Pro.
Check that it works
- Go to Content → Articles.
- Open a published article and click Save & Close.
Above the list you'll see Sent to IndexNow (200), followed by the article's address. A 200 means Bing found your key file and took the address. A 202 means Bing got the address but hasn't checked your key yet. If it stays at 202, open your key file in the browser again and compare it with the key in the snippet.
A warning that reads IndexNow failed with a number means Bing turned the request down. The IndexNow documentation lists what each number means.
Google doesn't use IndexNow, so it still finds your changes through your sitemap and its own crawler. To tell search engines when an article last changed, see Add Published and Modified Date Meta Tags to Joomla. To learn more about how PHP snippets work, read the PHP snippet docs.