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.

Submit Updated Articles to Bing and Yandex with IndexNow in Joomla
Heads up! This article contains PHP code and is intended for developers. We offer this code as a courtesy, but don't provide support for code customizations or 3rd party development.

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.

  1. Open Bing's IndexNow page and generate a key. Any 8 to 128 letters, numbers and dashes work too.
  2. Create a text file named after the key, like a1b2c3d4e5f6a7b8.txt, that holds only the key.
  3. Upload the file to your Joomla root folder, the one with configuration.php in it, with your host's file manager or FTP.
  4. Open https://www.example.com/a1b2c3d4e5f6a7b8.txt in 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

  1. Install Code Snippets if it isn't installed already.
  2. Log into your Joomla backend.
  3. Go to Components → Tassos Code Snippets.
  4. Click New.
  5. Enter a title, for example IndexNow.
  6. Set Code Type to PHP.
  7. Set Insertion Method to Auto-Insert Locations.
  8. Set Location to Admin Page Load.
  9. Paste the code above into the editor.
  10. Click Save & Close.

Admin locations are part of Code Snippets Pro.

Check that it works

  1. Go to Content → Articles.
  2. 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.

Joomla runs nothing when a scheduled article goes live, so the snippet can't send it then. Save the article once more after its publish date.

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.

Last updated on Oct 20th 2026 09:10