Giscus란?
Giscus는 Utterances에서 영감을 받아 만들어진 GitHub Discussion 기반의 오픈소스 댓글 서비스입니다.
- Utterances: GitHub Issues 활용
- Giscus: GitHub Discussions 활용
왜 Giscus인가요?
둘 다 훌륭한 서비스지만, Giscus는 다음과 같은 강력한 기능을 제공합니다.
- ✅ 대댓글 작성 가능
- ✅ 댓글 및 답글 수 확인 가능
- ✅ 댓글 정렬 (오래된 순, 새로운 순)
- ✅ 게시물에 대한 반응(Emoji) 남기기
- ✅ 다양한 테마 및 다국어 지원 (한국어 포함)
- ✅ 지연 로딩(Lazy Loading) 기능 및 귀여운 UI
1. 사전 준비: GitHub 설정
Giscus는 GitHub Discussion을 기반으로 하므로, 댓글이 저장될 저장소의 설정을 변경해야 합니다.
Step 1: GitHub Discussion 활성화
- 댓글을 저장할 Repository의 Settings로 이동합니다.
- Features 섹션에서 Discussions 체크박스를 활성화합니다.
Tip: 별도의 Repository를 만들어도 되지만, 블로그 Repository를 그대로 사용해도 무관합니다.
Step 2: 댓글 전용 Category 생성
기존 카테고리를 써도 좋지만, 깔끔한 관리를 위해 전용 카테고리를 만드는 것을 추천합니다.
- Repository의 Discussions 탭으로 이동합니다.
- 카테고리 편집에서
Comments라는 이름의 카테고리를 생성합니다. - (선택 사항) 사용하지 않는 기본 카테고리들은 정리해 줍니다.
2. Giscus 설정 및 설치
Step 1: Giscus GitHub App 설치
Giscus GitHub App에 접속하여 본인의 Repository에 설치를 진행합니다.
Step 2: Giscus Customization
giscus.app 공식 사이트에서 다음 설정을 진행합니다.
- Repository 연결:
사용자명/저장소명형식으로 입력합니다. - Mapping 설정: 게시글과 Discussion을 연결하는 방식을 선택합니다. (권장:
제목이 페이지 경로를 포함) - Category 선택: 앞서 만든
Comments카테고리를 선택합니다. - 테마 및 기능: 본인의 블로그 스타일에 맞춰 옵션을 체크합니다.
설정을 마치면 하단에 Script 태그가 생성됩니다. 일반 HTML 환경이라면 이 태그를 그대로 붙여넣으면 되지만, Next.js 환경에서는 최적화가 필요합니다.
3. Next.js에 Giscus 적용하기
Next.js 프로젝트에서는 테마 전환 반응성 및 부작용 방지를 위해 별도의 컴포넌트로 분리하는 것이 좋습니다.
Giscus 컴포넌트 작성
next-themes를 사용하는 환경을 기준으로 작성된 코드입니다.
"use client";
import { useEffect, useRef } from "react";
import { useTheme } from "next-themes";
export default function Giscus() {
const ref = useRef<HTMLDivElement>(null);
const { resolvedTheme } = useTheme();
// 테마 설정 (다크모드 대응)
const theme = resolvedTheme === "dark" ? "dark" : "light";
useEffect(() => {
if (!ref.current || ref.current.hasChildNodes()) return;
const scriptElem = document.createElement("script");
scriptElem.src = "https://giscus.app/client.js";
scriptElem.async = true;
scriptElem.crossOrigin = "anonymous";
// Giscus 설정 사이트에서 생성된 본인의 데이터를 입력하세요
scriptElem.setAttribute("data-repo", "사용자명/저장소명");
scriptElem.setAttribute("data-repo-id", "R_xxxxxxxx");
scriptElem.setAttribute("data-category", "Comments");
scriptElem.setAttribute("data-category-id", "DIC_xxxxxxxx");
scriptElem.setAttribute("data-mapping", "pathname");
scriptElem.setAttribute("data-strict", "0");
scriptElem.setAttribute("data-reactions-enabled", "1");
scriptElem.setAttribute("data-emit-metadata", "0");
scriptElem.setAttribute("data-input-position", "bottom");
scriptElem.setAttribute("data-theme", theme);
scriptElem.setAttribute("data-lang", "ko");
ref.current.appendChild(scriptElem);
}, [theme]);
// 테마 변경 시 Giscus 테마도 실시간으로 변경
useEffect(() => {
const iframe = document.querySelector<HTMLIFrameElement>(
"iframe.giscus-frame",
);
iframe?.contentWindow?.postMessage(
{ giscus: { setConfig: { theme } } },
"https://giscus.app",
);
}, [theme]);
return <section ref={ref} />;
}게시글 페이지에 적용
상세 페이지 하단에 Giscus 컴포넌트를 배치합니다.
const PostDetail = async ({ params: { category, slug } }: Props) => {
const post = await getPostDetail(category, slug);
return (
<div>
<PostHeader post={post} />
<PostBody post={post} />
{/* 댓글 섹션 추가 */}
<Giscus />
</div>
);
};마치며
이제 블로그 하단에서 성공적으로 작동하는 Giscus 댓글창을 확인할 수 있습니다! GitHub Discussions를 통해 관리되기 때문에 별도의 DB 없이도 안정적으로 댓글 기능을 운영할 수 있다는 점이 정말 매력적입니다.
도움이 되셨나요? 혹시 Giscus 테마 커스텀이나 data-mapping 전략에 대해 더 궁금한 점이 있다면 말씀해 주세요!
