---
title: "IndexNow"
description: "Instantly notify search engines when your content changes."
canonical_url: "https://nuxtseo.com/docs/ai-ready/guides/indexnow"
last_updated: "2026-05-06T18:46:32.174Z"
---

IndexNow is a protocol for instantly notifying search engines when URLs change, enabling faster indexing than waiting for crawlers.

Nuxt AI Ready supports IndexNow for both **static sites** (build-time) and **server-rendered sites** (runtime).

## Supported Search Engines

Submitting to IndexNow notifies all participating engines:

<table>
<thead>
  <tr>
    <th>
      Engine
    </th>
    
    <th>
      Endpoint
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Bing
    </td>
    
    <td>
      api.indexnow.org
    </td>
  </tr>
  
  <tr>
    <td>
      Yandex
    </td>
    
    <td>
      yandex.com/indexnow
    </td>
  </tr>
  
  <tr>
    <td>
      Naver
    </td>
    
    <td>
      searchadvisor.naver.com/indexnow
    </td>
  </tr>
  
  <tr>
    <td>
      Seznam
    </td>
    
    <td>
      search.seznam.cz/indexnow
    </td>
  </tr>
</tbody>
</table>

## Getting Started

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  aiReady: {
    indexNow: true
  }
})
```

That's it. A stable key is derived from your site URL automatically.

## Static Sites (Build-Time)

For static sites generated with `nuxi generate`, IndexNow submissions happen automatically at build time using **hash-based change detection**.

### How It Works

```text
┌─────────────────────────────────────────────────────────────┐
│ First Deploy                                                 │
│   Build → generate page hashes → create pages.meta.json     │
│   No previous meta found → skip IndexNow                    │
├─────────────────────────────────────────────────────────────┤
│ Subsequent Deploys                                           │
│   Build → fetch pages.meta.json from live site              │
│   Compare hashes → detect changes (modified/added pages)    │
│   Submit changed URLs to IndexNow                           │
│   Write new pages.meta.json for next deploy                 │
└─────────────────────────────────────────────────────────────┘
```

Each page gets a content hash stored in `/__ai-ready/pages.meta.json`. On subsequent builds, the module compares hashes to detect which pages changed and only submits those URLs to IndexNow.

### Pages Metadata Endpoint

```bash
GET /__ai-ready/pages.meta.json
```

```json
{
  "buildId": "abc123",
  "pageCount": 50,
  "createdAt": "2025-01-15T10:30:00Z",
  "pages": [
    { "route": "/", "hash": "986b464b8e7db2cb" },
    { "route": "/about", "hash": "150f2c142a4edb9d" }
  ]
}
```

### Static Site Setup

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  aiReady: {
    indexNow: true
  }
})
```

Run `nuxi generate` and deploy. Changed pages will be submitted to IndexNow automatically.

## Server-Rendered Sites (Runtime)

For SSR sites, IndexNow syncs pages that were indexed at runtime. Enable with `cron: true` or call the sync endpoint manually.

### Automatic Syncing (Cron)

When `cron: true`, IndexNow syncs automatically every minute after indexing runs:

```text
┌─────────────────────────────────────────────────────────────┐
│ Cron triggers ai-ready task (every minute)                   │
│           ↓                                                  │
│ batchIndexPages() → index pending pages                     │
│           ↓                                                  │
│ syncToIndexNow() → submit changed pages to search engines   │
│                  → update indexnow_synced_at                │
└─────────────────────────────────────────────────────────────┘
```

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  aiReady: {
    cron: true,
    indexNow: true
  }
})
```

### Manual Sync via Endpoint

For manual integration, use `POST /__ai-ready/indexnow` endpoint directly.

## API Endpoints

### Key Verification

Search engines verify your key at `/{key}.txt`:

```bash
GET /your-api-key.txt
# Returns: your-api-key
```

The module automatically registers this route.

### Sync Endpoint

Submit pending pages to IndexNow:

```bash
POST /__ai-ready/indexnow?limit=100
# Requires header: Authorization: Bearer <token>
```

<table>
<thead>
  <tr>
    <th>
      Param
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        limit
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        100
      </code>
    </td>
    
    <td>
      Max URLs per batch
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Authorization
      </code>
      
       header
    </td>
    
    <td>
      <code className="language-html shiki shiki-themes github-light github-light material-theme-palenight" language="html" style="">
        <span class="sqjlB">
          Bearer
        </span>
        
        <span class="sx-uw">
          <
        </span>
        
        <span class="sFfpx">
          token
        </span>
        
        <span class="sx-uw">
          >
        </span>
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      Required if <code>
        runtimeSyncSecret
      </code>
      
       configured
    </td>
  </tr>
</tbody>
</table>

**Response:**

```json
{
  "success": true,
  "submitted": 50,
  "remaining": 150,
  "error": null
}
```

### Status Endpoint

Check IndexNow stats:

```bash
GET /__ai-ready/status
```

```json
{
  "total": 100,
  "indexed": 95,
  "pending": 5,
  "indexNow": {
    "pending": 10,
    "totalSubmitted": 500,
    "lastSubmittedAt": 1704067200000,
    "lastError": null
  }
}
```

## Integration with Runtime Sync

Chain IndexNow after polling using the [CLI](/docs/ai-ready/guides/cli):

```bash
# Index new/changed pages
npx nuxt-ai-ready poll --all

# Notify search engines of changes
npx nuxt-ai-ready indexnow
```

For production, specify the URL:

```bash
npx nuxt-ai-ready poll --all --url https://mysite.com
npx nuxt-ai-ready indexnow --url https://mysite.com
```

Or trigger from a scheduled task/cron job:

```ts [server/tasks/sync-search-engines.ts]
import { syncToIndexNow } from '#ai-ready'

export default defineTask({
  meta: { name: 'sync-search-engines' },
  async run({ payload, context }) {
    const result = await syncToIndexNow(context.event, 100)
    return { result: `Submitted ${result.submitted} URLs` }
  }
})
```

## Rate Limits & Fallback

IndexNow has generous limits:

- Up to 10,000 URLs per request
- Up to 100,000 URLs per day

The module handles rate limits automatically:

1. **Fallback to Bing**: If `api.indexnow.org` returns 429, the module retries via `www.bing.com/indexnow`
2. **Exponential backoff**: On repeated rate limits, backs off from 5min → 10min → 20min → 40min → 1hr

## Troubleshooting

### Key Verification Fails

Ensure your key route is accessible:

```bash
curl https://yoursite.com/your-api-key.txt
# Should return: your-api-key
```

### Submissions Fail

Check the status for errors:

```bash
npx nuxt-ai-ready status
```

Common errors:

- `403`: Key not found at keyLocation
- `422`: URLs don't match host
- `429`: Rate limited
