2026-03-12
IndexNow 연동기 — 블로그 글 발행하면 검색엔진에 자동 알림
들어가며
블로그에 글을 발행하고 나서 Google에 검색해봤다. 안 뜬다. 하루 지나도 안 뜬다. Google Search Console에 들어가서 URL 검사 → 색인 생성 요청을 수동으로 해야 겨우 며칠 뒤에 인덱싱이 된다.
글 쓸 때마다 이 짓을 하고 있으니, 자동화하고 싶어졌다. 찾아보니 IndexNow라는 프로토콜이 있다. Bing, Yandex 등이 지원하고, URL이 변경됐을 때 검색엔진에 즉시 알릴 수 있다.
IndexNow가 뭔데
IndexNow는 Microsoft가 주도하는 오픈 프로토콜이다. 웹사이트가 콘텐츠를 추가/수정/삭제했을 때, 검색엔진에 "이 URL이 바뀌었으니 다시 크롤링해라"고 알려주는 방식이다.
기존 방식은 검색엔진이 알아서 사이트맵을 크롤링하고, 변경 사항을 감지하는 풀(pull) 방식이었다. IndexNow는 반대로 사이트가 검색엔진에 직접 알려주는 푸시(push) 방식이다.
지원하는 검색엔진
- Bing — Microsoft 검색엔진
- Yandex — 러시아 최대 검색엔진
- Seznam — 체코 검색엔진
- Naver — 네이버도 지원 (2023년부터)
Google은 아직 공식 지원하지 않지만, 향후 지원 가능성을 열어두고 있다. Google 색인은 여전히 Search Console 수동 제출이나 사이트맵 크롤링에 의존해야 한다.
구현
1. API 키 생성
IndexNow는 API 키로 사이트 소유권을 검증한다. 키는 아무 UUID나 생성하면 된다. 이 키를 환경 변수로 저장한다.
# .env
INDEXNOW_API_KEY=your-uuid-key-here2. 키 검증 엔드포인트
IndexNow는 API 호출 시 keyLocation에 지정된 URL로 접근해서 키 값을 확인한다. Next.js route handler로 간단하게 만들었다.
// src/app/indexnow-verify/route.ts
export async function GET() {
const key = process.env.INDEXNOW_API_KEY;
if (!key) return new Response('Not configured', { status: 404 });
return new Response(key, {
headers: { 'Content-Type': 'text/plain' },
});
}이렇게 하면 https://zerry.co.kr/indexnow-verify에 접근하면 키 값이 텍스트로 반환된다. 빌드 시 정적 파일을 생성할 필요 없이 런타임에 동적으로 제공하는 방식이다.
3. 알림 함수
// src/lib/indexing.ts
const SITE_URL = 'https://zerry.co.kr';
async function submitIndexNow(url: string) {
const key = process.env.INDEXNOW_API_KEY;
if (!key) return;
try {
await fetch('https://api.indexnow.org/indexnow', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
host: 'zerry.co.kr',
key,
keyLocation: `${SITE_URL}/indexnow-verify`,
urlList: [url],
}),
});
} catch (e) {
console.error('[indexnow] submit failed:', e);
}
}
export async function notifySearchEngines(slug: string) {
const url = `${SITE_URL}/blog/${slug}`;
await submitIndexNow(url);
}urlList에 여러 URL을 한 번에 보낼 수도 있다. 하지만 블로그에서는 글 하나씩 발행하니까 하나만 보낸다.
4. API 연동
글 발행 시 after()로 백그라운드에서 알림을 보낸다. 응답 속도에 영향을 주지 않는다.
// src/app/api/posts/route.ts
import { after } from 'next/server';
import { notifySearchEngines } from '@/lib/indexing';
export async function POST(req: NextRequest) {
// ... 글 저장
if (status !== 'draft') {
after(async () => {
await notifySearchEngines(slug);
});
}
return NextResponse.json({ slug });
}초안(draft)일 때는 보내지 않고, 발행(published)할 때만 보낸다. 글 비발행(published → draft)이나 삭제 시에도 IndexNow를 호출해서 검색엔진이 해당 URL을 빨리 제거하도록 했다.
Google은 어쩌나
솔직히 이게 가장 아쉬운 부분이다. IndexNow가 Google을 지원하지 않기 때문에, Google 색인은 여전히 다른 방법이 필요하다.
Google Sitemap Ping은 이미 죽었다
예전에는 https://www.google.com/ping?sitemap=URL로 사이트맵 변경을 알릴 수 있었다. 하지만 Google은 2023년에 이 엔드포인트를 deprecated했다. 200 OK를 반환하긴 하지만 아무 동작도 하지 않는다.
현실적인 Google 대응
- 사이트맵 제출 — Search Console에서 sitemap.xml을 제출해두면 Google이 주기적으로 크롤링한다
- URL 검사 → 색인 생성 요청 — 급한 글은 수동으로 요청. 하루 약 10개 제한
- 시간이 해결 — 사이트 신뢰도가 올라가면 크롤링 빈도가 자연히 증가한다
결국 Google은 "기다려라"가 답이다. IndexNow로 Bing/Yandex/Naver에는 즉시 알리고, Google은 사이트맵과 자연 크롤링에 맡기는 전략이다.
배포 후 확인
Vercel에 INDEXNOW_API_KEY 환경 변수를 추가하고 배포했다. 글을 하나 발행해보니 Vercel 로그에 IndexNow API 호출이 찍히는 걸 확인했다.
Bing Webmaster Tools에서 확인해보면, IndexNow로 제출된 URL 목록과 상태를 볼 수 있다. 제출 후 몇 시간 내에 Bing 검색 결과에 노출되기 시작한다.
정리
| 항목 | 내용 |
|---|---|
| 프로토콜 | IndexNow — 사이트가 검색엔진에 URL 변경을 푸시 |
| 지원 검색엔진 | Bing, Yandex, Seznam, Naver |
| 미지원 — 사이트맵/수동 제출 필요 | |
| 구현 난이도 | 매우 쉬움 — fetch 한 번이면 끝 |
| 적용 위치 | 글 발행/비발행/삭제 시 after()로 호출 |
구현 자체는 30분이면 끝난다. API 키 하나 만들고, 검증 엔드포인트 하나 만들고, 글 발행 API에 fetch 한 줄 추가하면 된다. 이걸로 Bing, Naver 등에서의 색인 속도가 눈에 띄게 빨라진다. Google만 빼고.
관련 글
벡터 유사도 기반Next.js after() — 응답 먼저, 무거운 작업은 나중에
Next.js 15의 after() API로 응답 속도를 희생하지 않으면서 백그라운드 작업을 처리하는 방법.
83% 일치Next.js에서 OG 이미지 자동 생성하기 — Satori로 삽질한 이야기
Next.js ImageResponse(Satori)로 블로그 OG 이미지를 자동 생성한 경험기. CSS 제약사항, 폰트 로딩, 디자인 변천사까지.
82% 일치개인 블로그에 단축 URL 만들기 — /p/[id]로 한글 URL 문제 해결
한글 slug가 URL 인코딩되면 엄청 길어지는 문제를 자체 단축 URL과 301 리다이렉트로 해결한 과정.