---
title: "IndexNow and Indexing APIs in Vue"
description: "Push URL changes to Bing and Yandex instantly with IndexNow, and see where Google's Indexing API actually helps in a Vue app."
canonical_url: "https://nuxtseo.com/learn-seo/vue/launch-and-listen/indexnow"
last_updated: "2026-07-16"
---

<key-takeaways>

- IndexNow pushes URL changes straight to Bing, Yandex, Naver, Seznam.cz, and Yep; Google does not participate
- The Google Indexing API only works for pages marked up with JobPosting or BroadcastEvent schema, everything else gets ignored
- RequestIndexing submits to Google's real Indexing API on your behalf via OAuth, it isn't a browser-automation workaround

</key-takeaways>

Search engines discover content changes by crawling on their own schedule, and Google won't commit to a timeline for how long that takes. Indexing APIs let you skip the wait and notify a search engine the moment you publish, update, or delete content.

## IndexNow Protocol

IndexNow is an [open-source protocol](https://www.indexnow.org/) that notifies search engines instantly when URLs change. Instead of waiting for crawlers to discover updates, you push notifications directly to participating engines.

Supported search engines:

- Microsoft Bing, the protocol's primary backer
- Yandex, Russia's largest search engine
- Seznam.cz, the leading Czech search engine
- Naver, South Korea's leading search engine
- Yep, Ahrefs' privacy-focused search engine

Google does not support IndexNow. Use Google Search Console's manual "Request Indexing" feature, or one of the tools covered below.

IndexNow is also the fastest way to get content into Bing and Copilot's index, since Copilot answers draw on Bing's search index. Bing has said [sitemaps and IndexNow both feed how it surfaces content in AI-powered search](https://blogs.bing.com/webmaster/July-2025/Keeping-Content-Discoverable-with-Sitemaps-in-AI-Powered-Search). Whether [Perplexity](https://perplexity.ai) benefits isn't confirmed by any of its own documentation, so treat that as speculative rather than a reason to adopt IndexNow on its own.

### When to Use IndexNow

Use IndexNow when:

- Publishing new content (blog posts, product pages)
- Updating existing pages (price changes, corrections)
- Deleting pages (discontinued products, removed content)
- Fixing critical errors on important pages
- Running time-sensitive content (news, events, flash sales)

Don't use IndexNow for:

- Minor text edits or typo fixes
- Styling or layout changes
- Pages already noindexed via robots meta tag
- Private or staging content

### Setting Up IndexNow

Generate an API key. The spec requires 8 to 128 characters, using only letters, numbers, and dashes:

```bash
openssl rand -hex 32
```

Create a key file in your `public` directory:

```txt [public/abc123def456.txt]
abc123def456
```

The key must be accessible at `https://yoursite.com/{key}.txt` for verification.

### Submitting URLs

Submit URLs after content changes. One notification reaches all IndexNow engines.

<code-group>

```ts [Express]
import express from 'express'

const app = express()

async function notifyIndexNow(urls: string[]) {
  await fetch('https://api.indexnow.org/indexnow', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      host: 'yoursite.com',
      key: 'abc123def456',
      keyLocation: 'https://yoursite.com/abc123def456.txt',
      urlList: urls
    })
  })
}

// Trigger after publishing
app.post('/api/publish', async (req, res) => {
  // Save content to database
  await db.posts.create(req.body)

  // Notify search engines
  await notifyIndexNow([`https://yoursite.com/blog/${req.body.slug}`])

  res.json({ success: true })
})
```

```ts [Vite Plugin]
// vite-plugin-indexnow.ts
import type { Plugin } from 'vite'

export function indexNowPlugin(options: { key: string, host: string }): Plugin {
  return {
    name: 'vite-plugin-indexnow',
    async closeBundle() {
      const urls = [
        `https://${options.host}/`,
        `https://${options.host}/about`,
        // Add your generated URLs
      ]

      await fetch('https://api.indexnow.org/indexnow', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          host: options.host,
          key: options.key,
          urlList: urls
        })
      })

      console.log(`Notified IndexNow: ${urls.length} URLs`)
    }
  }
}
```

```ts [H3 API Route]
import { defineEventHandler, readBody } from 'h3'

export default defineEventHandler(async (event) => {
  const { urls } = await readBody(event)

  await fetch('https://api.indexnow.org/indexnow', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      host: 'yoursite.com',
      key: process.env.INDEXNOW_KEY,
      keyLocation: `https://yoursite.com/${process.env.INDEXNOW_KEY}.txt`,
      urlList: urls
    })
  })

  return { success: true, count: urls.length }
})
```

```ts [CMS Integration]
// In your CMS save handler
async function savePost(post) {
  await database.save(post)

  // Notify IndexNow if published
  if (post.status === 'published') {
    await fetch('https://api.indexnow.org/indexnow', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        host: 'yoursite.com',
        key: process.env.INDEXNOW_KEY,
        urlList: [post.url]
      })
    })
  }
}
```

</code-group>

Submit up to 10,000 URLs per request. For single URLs, use GET:

```txt
https://api.indexnow.org/indexnow?url=https://yoursite.com/page&key=abc123def456
```

## Google Indexing API

[Google's Indexing API](https://developers.google.com/search/apis/indexing-api/v3/quickstart) works differently than IndexNow: it's limited to `JobPosting` and `BroadcastEvent` schema types only.

Don't use Google's Indexing API for:

- Blog posts
- Product pages
- General website content
- News articles
- Landing pages

Only use it if your site has:

- Job listings with JobPosting schema
- Livestream videos with BroadcastEvent schema

Using the API for other content types doesn't help you and doesn't hurt you: Google [confirmed](https://developers.google.com/search/apis/indexing-api/v3/quickstart) that submissions outside JobPosting and BroadcastEvent are simply ignored.

The default quota is [200 publish requests per day per project](https://developers.google.com/search/apis/indexing-api/v3/quota-pricing), resetting at midnight Pacific. To go beyond that you submit a quota-increase request through Google Cloud, not a general "partner authorization" process, and approval is still limited to JobPosting and BroadcastEvent content. If you run a job board, follow the [official quickstart](https://developers.google.com/search/apis/indexing-api/v3/quickstart) and request a quota increase from there.

## RequestIndexing Tool

[RequestIndexing](https://requestindexing.com/) by [@harlan_zw](https://x.com/harlan_zw) uses your Search Console OAuth credentials to submit URLs directly to Google's Indexing API, then polls the API for status. Google's Indexing API accepts one URL per call; RequestIndexing handles the bulk submission and polling for you.

Use cases:

- Bulk indexing after site migration
- Re-indexing updated content
- Submitting new pages when sitemaps aren't crawled quickly
- Emergency indexing for time-sensitive content

Limitations:

- Requires Google Search Console access
- Subject to Google's daily quota
- Still depends on Googlebot's crawl queue to process the page, submission isn't the same as indexing

## Choosing the Right Method

Pick based on search engine priority and content type:

<table>
<thead>
  <tr>
    <th>
      Method
    </th>
    
    <th>
      Best For
    </th>
    
    <th>
      Limitations
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      IndexNow
    </td>
    
    <td>
      Bing/Yandex users, instant updates
    </td>
    
    <td>
      Doesn't work for Google
    </td>
  </tr>
  
  <tr>
    <td>
      Google Indexing API
    </td>
    
    <td>
      Job boards, livestreams
    </td>
    
    <td>
      JobPosting/BroadcastEvent only
    </td>
  </tr>
  
  <tr>
    <td>
      RequestIndexing
    </td>
    
    <td>
      Bulk Google submissions
    </td>
    
    <td>
      Still subject to Google's quota
    </td>
  </tr>
  
  <tr>
    <td>
      Search Console Manual
    </td>
    
    <td>
      One-off important pages
    </td>
    
    <td>
      Slow, not scalable
    </td>
  </tr>
  
  <tr>
    <td>
      XML Sitemap
    </td>
    
    <td>
      Routine crawling
    </td>
    
    <td>
      Passive, no urgency signal
    </td>
  </tr>
</tbody>
</table>

Implement IndexNow for all content changes: your Bing and Yandex traffic gets instant updates. For Google, use XML sitemaps for routine discovery and RequestIndexing for bulk submissions after major updates. Skip the Google Indexing API unless you run a job board or livestream platform.

## Using Nuxt?

If you're on Nuxt rather than plain Vue, the [`nuxt-ai-ready`](https://nuxtseo.com/docs/ai-ready/guides/indexnow) module wires this up for you: enable `aiReady: { indexNow: true }` and it derives a stable key from your site URL, serves the key file, and submits changed URLs automatically (hash-based diffing at build time for static sites, a `POST /__ai-ready/indexnow` endpoint plus a minute-by-minute sync for SSR sites). See the [Nuxt IndexNow guide](/learn-seo/nuxt/launch-and-listen/indexnow) for the full setup.

## Checklist

<checklist id="vue-indexnow">

- Generate an IndexNow key and serve it at `/{key}.txt`
- Wire a server endpoint or build step that calls the IndexNow API on publish/update
- Submit your sitemap to Google Search Console for Google discovery
- Reserve the Google Indexing API for JobPosting/BroadcastEvent content only
- Use RequestIndexing for bulk or urgent Google re-crawls, not routine publishing

</checklist>
