Giscus를 이용한 댓글 기능 구현
- Giscus는 GitHub 저장소의 Discussions를 이용한 댓글 기능을 제공하는 무료 서비스입니다. (Powered by Vercel)
- 1in.dev에서 사용하는 댓글 기능입니다.
-
사용자들이 Github 계정을 가지고 있는 개발자 대상 서비스에서 사용하기 좋습니다.
<script>
형태로 사용할 수 있고, React/Vue/Svelte 등의 컴포넌트로도 사용할 수 있습니다.- 자세한 설정이나 사용 방법은 https://giscus.app/ko 에서 확인할 수 있습니다.
1. 기본 설정
- GitHub 저장소를 공개로 설정
- 해당 저장소의 Discussions 기능 활성화 (Settings > Features > Discussions ✅ 체크)
- GitHub에서 giscus 앱 설치 (원하는 저장소에만 설치하거나 모든 저장소에 설치)
- giscus.app 웹사이트에서 Giscus를 연결할 저장소 링크를 추가하여 코드를 얻습니다. (repo, repoId, category, categoryId 등)
- Giscus
<script>
코드 또는 컴포넌트를 원하는 웹페이지에 추가
2. React/Vue/Svelte 컴포넌트 설정
자세한 사용 방법은 https://github.com/giscus/giscus-component 에서 확인
Giscus 패키지 설치
npm install @giscus/react
# or
npm i @giscus/vue # for Vue
npm i @giscus/svelte # for Svelte
npm i @giscus/solid # for Solid
컴포넌트 생성
// components/comment/giscus.jsx
import Giscus from "@giscus/react";
export default function CommentSection() {
return (
<Giscus
repo="your-github-username/your-repo-name"
repoId="your-repo-id"
category="Announcements" // GitHub Discussions 카테고리 이름
categoryId="your-category-id"
mapping="pathname" // 페이지와 디스커션을 매핑하는 방법
reactionsEnabled="1"
emitMetadata="0"
inputPosition="top" // 댓글 입력창 위치
theme="light" // 테마 (light, dark, preferred_color_scheme 등)
lang="ko" // 언어 설정
loading="lazy"
/>
);
}
컴포넌트 사용
import Giscus from "@/components/comment/giscus";
// 페이지 내용
<br />
<Giscus />
3. Dark/Light Mode에 따라 테마 변경하는 컴포넌트 예시
import Giscus from "@giscus/react";
import { useTheme } from "next-themes";
import { useEffect, useState } from "react";
// 사용 가능한 테마 목록을 상수로 정의
export const GISCUS_THEMES = {
light: [
"light",
"light_high_contrast",
"light_protanopia_deuteranopia",
"light_tritanopia",
"noborder_light",
"gruvbox_light",
"catppuccin_latte",
],
dark: [
"dark",
"dark_high_contrast",
"dark_protanopia_deuteranopia",
"dark_tritanopia",
"dark_dimmed",
"transparent_dark",
"noborder_dark",
"noborder_gray",
"rstudio_cobalt",
"purple_dark",
"gruvbox_dark",
"catppuccin_frappe",
"catppuccin_macchiato",
"catppuccin_mocha",
"fro",
],
auto: ["preferred_color_scheme"],
custom: ["custom"],
};
export default function GiscusComponent() {
const { theme } = useTheme();
const [mounted, setMounted] = useState(false);
// 컴포넌트가 마운트된 후에만 렌더링
useEffect(() => {
setMounted(true);
}, []);
// 테마에 따른 giscus 테마 선택
const getGiscusTheme = () => {
if (theme === "dark") return "dark_high_contrast";
if (theme === "light") return "light_high_contrast";
return "preferred_color_scheme";
};
// 마운트되기 전에는 아무것도 렌더링하지 않음
if (!mounted) return null;
return (
<Giscus
key={theme} // theme이 변경될 때마다 컴포넌트를 다시 마운트
id="comments"
repo="Integerous/giscus-test"
repoId="R_kgDOOMnFRQ"
category="Announcements"
categoryId="DIC_kwDOOMnFRc4CoVUk"
mapping="pathname"
term="1in.dev"
reactionsEnabled="1"
emitMetadata="0"
inputPosition="top"
// theme="preferred_color_scheme"
theme={getGiscusTheme()}
lang="ko"
loading="lazy"
/>
);
}