
Astro + Netlify 블로그에 IndexNow 자동 색인 요청 적용하기
새 글 발행할 때마다 수동으로 색인 요청하기 귀찮다면? Netlify Build Plugin으로 Naver, Bing 자동 색인 요청 구현 완벽 가이드
블로그를 운영하다 보면 새 글을 발행할 때마다 검색엔진에 색인 요청을 해야 한다. Google Search Console, Naver Search Advisor, Bing Webmaster Tools… 하나씩 들어가서 URL을 입력하는 게 여간 귀찮은 일이 아니다.
특히 초기 블로그는 검색엔진이 자동으로 크롤링해주는 주기가 길어서 (며칠~몇 주) 수동 색인 요청이 거의 필수다. 이걸 자동화할 수는 없을까?
IndexNow가 뭔가요?
IndexNow는 Microsoft와 Yandex가 만든 프로토콜로, 웹사이트가 검색엔진에게 “이 URL이 새로 생겼어요!” 또는 “이 URL이 업데이트됐어요!”라고 즉시 알려주는 API다.
지원 검색엔진
- ✅ Bing (Microsoft)
- ✅ Naver
- ✅ Yandex
- ✅ Seznam.cz
지원 안 하는 검색엔진
- ❌ Google (자체 시스템만 사용)
Google은 IndexNow를 지원하지 않으므로, Google에는 별도로 Search Console에서 수동 요청하거나 Sitemap으로 대응해야 한다.
왜 IndexNow를 쓰려고 했나?
내 상황
- Astro로 만든 블로그
- Netlify로 SSG 배포
- Git push → 자동 배포
- 새 글 발행할 때마다 수동 색인 요청 중 😫
기존 방식의 문제점
- 시간 낭비: 매번 Search Console/Webmaster 들어가서 URL 입력
- 요청 제한: Google은 하루 10개만 수동 요청 가능
- 깜빡할 수 있음: 글 쓰는 데 집중하다 색인 요청 잊어버림
- 느린 자동 색인: Sitemap만 제출하면 며칠~몇 주 걸림
목표
Git push하면 → Netlify 빌드 완료 후 → 자동으로 IndexNow 요청
어떻게 구현했나?
1단계: IndexNow API 키 생성
IndexNow는 도메인 소유권 증명을 위해 API 키가 필요하다.
키 생성 방법
UUID 형식의 키를 생성한다. https://www.uuidgenerator.net/ 같은 사이트에서 생성 가능.
예시: a1b2c3d4-e5f6-7890-abcd-ef1234567890
키 파일 생성
/public/a1b2c3d4-e5f6-7890-abcd-ef1234567890.txt 파일을 만들고, 내용도 똑같이 입력:
a1b2c3d4-e5f6-7890-abcd-ef1234567890
중요: 파일명(확장자 제외)과 파일 내용이 완전히 동일해야 한다!
이 파일은 IndexNow가 https://yourblog.com/a1b2c3d4-e5f6-7890-abcd-ef1234567890.txt로 접속해서 도메인 소유권을 확인하는 용도다.
2단계: Netlify 환경변수 설정
Netlify Dashboard에서:
- Site settings → Environment variables
- Add variable
- Key:
INDEXNOW_KEY - Value:
a1b2c3d4-e5f6-7890-abcd-ef1234567890(1단계에서 생성한 키)
- Key:
코드에 직접 키를 쓰면 GitHub에 노출되므로 환경변수로 관리한다.
3단계: Netlify Build Plugin 작성
plugins/indexnow/index.js:
export default {
async onSuccess() {
const INDEXNOW_KEY = process.env.INDEXNOW_KEY;
if (!INDEXNOW_KEY) {
console.log('❌ INDEXNOW_KEY 환경변수가 설정되지 않았습니다');
return;
}
const { execSync } = await import('child_process');
// Git으로 변경된 블로그 파일만 찾기
let changedFiles = [];
try {
changedFiles = execSync(
'git diff --name-only HEAD~1 HEAD -- "src/content/blog/**/*.{md,mdx}"',
{ encoding: 'utf-8' }
)
.trim()
.split('\n')
.filter(Boolean);
} catch (e) {
console.log('⚠️ 변경된 파일 없음');
return;
}
if (changedFiles.length === 0) {
console.log('✅ 새 블로그 글 없음 - IndexNow 건너뜀');
return;
}
// 변경된 파일을 URL로 변환
const urls = changedFiles.map(file => {
const slug = file
.replace('src/content/blog/', '')
.replace(/\.(md|mdx)$/, '');
return `https://yourblog.com/blog/${slug}`;
});
// IndexNow API 호출
try {
const response = await fetch('https://api.indexnow.org/indexnow', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
host: 'yourblog.com',
key: INDEXNOW_KEY,
keyLocation: `https://yourblog.com/${INDEXNOW_KEY}.txt`,
urlList: urls
})
});
if (response.ok) {
console.log(`✅ IndexNow 제출 완료: ${urls.length}개 URL (Bing, Naver)`);
urls.forEach(url => console.log(` 📄 ${url}`));
} else {
console.log(`❌ IndexNow 오류: ${response.status}`);
}
} catch (error) {
console.log(`❌ IndexNow 실패: ${error.message}`);
}
}
};
plugins/indexnow/manifest.yml:
name: indexnow-auto-submit
4단계: netlify.toml 설정
netlify.toml:
[[plugins]]
package = "./plugins/indexnow"
전체 파일 구조
프로젝트/
├── public/
│ └── [your-api-key].txt # API 키 파일
├── plugins/
│ └── indexnow/
│ ├── index.js # 플러그인 로직
│ └── manifest.yml # Netlify 플러그인 선언
└── netlify.toml # 플러그인 활성화
작동 방식
1. 새 글 작성/수정
2. Git commit & push
3. Netlify 자동 빌드 시작
4. Astro SSG 빌드 완료
5. onSuccess 훅 실행 ← 여기서 IndexNow 호출!
6. Git diff로 변경된 .md/.mdx 파일만 감지
7. IndexNow API에 URL 제출
8. Bing, Naver가 빠르게 크롤링
9. 배포 완료
Netlify 빌드 로그 예시:
✅ IndexNow 제출 완료: 2개 URL (Bing, Naver)
📄 https://yourblog.com/blog/my-awesome-post
📄 https://yourblog.com/blog/another-great-article
실제 경험과 팁
좋았던 점
- 완전 자동화: 글 쓰기에만 집중, 색인은 신경 안 써도 됨
- 변경 감지: Git diff로 새 글/수정된 글만 정확히 감지
- 빠른 색인: Naver, Bing 색인이 1 ~ 2일 내로 완료 (기존 1 ~ 2주 → 1 ~ 2일)
- 무료: Netlify 무료 플랜으로 충분 (월 125,000회 Function 호출 제공)
주의할 점
- Google은 별도: IndexNow로 해결 안 됨, Search Console 수동 요청 or 기다리기
- 샌드박스 기간: 새 도메인은 1~3개월 샌드박스 기간 있음
- 과도한 요청 금지: 같은 URL을 하루에 여러 번 요청하면 스팸 처리될 수 있음
- 작은 수정은 불필요: 오타 한 글자 고친 거로 색인 요청할 필요 없음
개선 아이디어
중복 방지 (24시간 내 재요청 방지)
캐시 파일로 최근 제출 이력 저장:
// 캐시 로드
let cache = {};
try {
cache = JSON.parse(await readFile('./indexnow-cache.json', 'utf-8'));
} catch (e) {}
const now = Date.now();
const ONE_DAY = 24 * 60 * 60 * 1000;
// 24시간 이내 제출한 URL 제외
const urlsToSubmit = urls.filter(url => {
const lastSubmit = cache[url];
if (!lastSubmit) return true;
return (now - lastSubmit) > ONE_DAY;
});
Frontmatter 플래그로 선택적 제출
중요한 글만 색인 요청:
---
title: "중요한 글"
indexNow: true # 이 플래그 있을 때만 색인 요청
---
대안: 수동 스크립트
완전 자동화가 부담스럽다면, 필요할 때만 실행하는 스크립트:
scripts/request-index.js:
const INDEXNOW_KEY = 'your-api-key-here';
// 사용법: node scripts/request-index.js blog/my-post
const slugs = process.argv.slice(2);
const urls = slugs.map(slug => `https://yourblog.com/blog/${slug}`);
await fetch('https://api.indexnow.org/indexnow', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
host: 'yourblog.com',
key: INDEXNOW_KEY,
keyLocation: `https://yourblog.com/${INDEXNOW_KEY}.txt`,
urlList: urls
})
});
console.log(`✅ 색인 요청 완료: ${urls.length}개`);
실행:
node scripts/request-index.js my-awesome-post another-article
결론
IndexNow는 설정만 제대로 하면 블로그 색인 관리를 완전히 자동화할 수 있는 강력한 도구다.
Naver와 Bing 색인이 빨라지면 초기 트래픽 확보에 큰 도움이 된다. Google은 여전히 수동 관리가 필요하지만, 전체 색인 관리 부담은 크게 줄어든다.
블로그를 막 시작했거나, 매번 수동 색인 요청이 귀찮다면 IndexNow를 강력히 추천한다.