---
title: "Submit Updated Articles to Bing and Yandex with IndexNow in Joomla - Code Snippets"
description: "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."
url: "https://www.tassos.gr/docs/code-snippets/howto/seo-meta-tags/indexnow"
date: "2026-10-22T23:52:24+00:00"
language: "en-GB"
---

[ Home ](https://www.tassos.gr/docs) / [ Code Snippets ](https://www.tassos.gr/docs/code-snippets) / [ How-to Guides ](https://www.tassos.gr/docs/code-snippets/howto) / [ SEO & Meta Tags ](https://www.tassos.gr/docs/code-snippets/howto/seo-meta-tags)

#  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](https://www.tassos.gr/images/2026/10/code-snippets-indexnow-card.png) 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](#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](https://www.bing.com/indexnow/getstarted) 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-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](#how-to-add-this-snippet)

1. Install [Code Snippets](https://www.tassos.gr/docs/code-snippets/getting-started/how-to-install) 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](https://www.tassos.gr/docs/code-snippets/locations/admin) are part of Code Snippets Pro.

## [Check that it works](#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](https://www.indexnow.org/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](https://www.tassos.gr/docs/code-snippets/howto/seo-meta-tags/article-date-meta-tags). To learn more about how PHP snippets work, read the [PHP snippet docs](https://www.tassos.gr/docs/code-snippets/types/php).

 Last updated on Oct 20th 2026 09:10
