본문 바로가기

백엔드·인프라

giscus·Disqus 대신 자체 D1 — 정적 블로그에 댓글·조회수·좋아요 직접 붙이기 (Cloudflare Pages Functions 따라하기)

반응형

정적 블로그(Next.js를 output: 'export'로 빌드한 사이트)에 댓글을 붙이려면 보통 giscus, Disqus, Utterances 같은 외부 위젯을 먼저 떠올려요. 저는 자체 D1을 골랐어요. 왜 그랬는지, 그리고 0부터 어떻게 붙이는지를 따라하기로 정리했어요.

왜 giscus·Disqus가 아니었나

  • giscus·Utterances는 댓글을 GitHub 이슈/디스커션에 저장해요. 그래서 독자가 댓글을 남기려면 GitHub 로그인을 해야 해요. 개발 블로그라도 일반 독자에겐 진입장벽이에요.
  • Disqus 무료 플랜은 광고가 붙고, 제3자 추적 스크립트라 개인정보(PIPA) 관점에서 부담이 있어요.
  • 둘 다 댓글 전용이라 조회수·방문자·좋아요는 따로 못 줘요.
  • 자체 D1은 같은 Cloudflare 배포 안에서 댓글·조회수·좋아요·방문자를 한 번에 처리해요. 데이터는 제 D1에만 있고, 외부 추적 스크립트는 0개예요. 익명 댓글이라 독자가 로그인할 필요도 없고요. 개인 블로그 트래픽이면 D1 무료 한도로 충분해요.

1) D1 만들고 바인딩하기

먼저 정적 결과물을 올리는 그 Pages 프로젝트의 wrangler.toml에 D1을 묶어요. 바인딩 이름(DB)이 코드에서 env.DB로 그대로 쓰여요.

[[d1_databases]]
binding = "DB"
database_name = "lifecarelog-blog-db"
database_id = "..."   # 아래 명령으로 생성 후 채우기
wrangler d1 create lifecarelog-blog-db

출력된 database_id를 위 설정에 붙여넣으면 연결 끝이에요.

2) 스키마 한 번에 적용하기

테이블은 마이그레이션 파일 하나로 만들어요. 조회수(post_views), 좋아요(post_likes), 댓글(comments), 방문자(visits) 네 가지를 한 파일에 담아 원격 D1에 실행해요.

wrangler d1 execute lifecarelog-blog-db --remote --file migrations/0001_init.sql

3) functions/ 폴더가 곧 API

여기가 핵심이에요. functions/ 안의 파일 경로가 그대로 엣지 API 라우트가 돼요. 따로 서버를 띄울 필요가 없어요. 예를 들어 functions/api/views/[slug].tsPOST /api/views/:slug가 돼요. Workers 런타임이라 Node가 아닌 Web 표준(Request/Response, crypto.subtle)을 쓴다는 점만 기억하면 돼요.

// functions/api/views/[slug].ts  →  POST /api/views/:slug
// 같은 방문자는 하루 한 번만 카운트
const dedup = await env.DB.prepare(
  'INSERT OR IGNORE INTO view_dedup (slug, visitor_hash, day) VALUES (?,?,?)',
).bind(slug, vh, todayUTC()).run();

if (dedup.meta.changes > 0) {
  await env.DB.prepare(
    'INSERT INTO post_views (slug, count) VALUES (?,1) ON CONFLICT(slug) DO UPDATE SET count = count + 1',
  ).bind(slug).run();
}

새로고침마다 조회수가 오르지 않게, view_dedup에 행이 실제로 들어갔을 때만 카운트를 올려요.

4) 시크릿은 코드에 두지 않기

방문자 해시용 솔트(HASH_SALT)와 댓글 삭제용 관리자 키(ADMIN_SECRET)는 절대 코드나 깃에 두면 안 돼요. 배포는 명령으로 주입하고, 로컬은 .dev.vars(gitignore)에 둬요.

wrangler pages secret put HASH_SALT
wrangler pages secret put ADMIN_SECRET

이렇게 네 단계면 정적 사이트 위에 동적 백엔드가 올라가요. 서버를 따로 운영하지 않고, 데이터는 내 손 안에 두면서요.

여러분은 정적 블로그 댓글을 외부 위젯으로 붙이세요, 아니면 직접 만드세요? 댓글로 어떤 방식을 쓰는지 알려주세요!

반응형