Skip to content

Commit 5fb65a0

Browse files
committed
feat : 댓글 기능 추가
1 parent 4441e44 commit 5fb65a0

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

src/components/utterances.tsx

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import React, { useEffect, useRef } from "react"
2+
3+
const Utterances: React.FC = () => {
4+
const commentsRef = useRef<HTMLDivElement>(null)
5+
6+
useEffect(() => {
7+
if (!commentsRef.current) return
8+
9+
// 현재 테마 감지
10+
const isDark = document.documentElement.classList.contains("dark")
11+
const theme = isDark ? "github-dark" : "github-light"
12+
13+
// 기존 스크립트 제거
14+
commentsRef.current.innerHTML = ""
15+
16+
// Utterances 스크립트 생성
17+
const script = document.createElement("script")
18+
script.src = "https://utteranc.es/client.js"
19+
script.setAttribute("repo", "pjj186/blog-comments")
20+
script.setAttribute("issue-term", "pathname")
21+
script.setAttribute("theme", theme)
22+
script.setAttribute("crossorigin", "anonymous")
23+
script.async = true
24+
25+
commentsRef.current.appendChild(script)
26+
27+
// 테마 변경 감지 함수
28+
const handleThemeChange = () => {
29+
const iframe =
30+
document.querySelector<HTMLIFrameElement>(".utterances-frame")
31+
if (iframe && iframe.contentWindow) {
32+
const newTheme = document.documentElement.classList.contains("dark")
33+
? "github-dark"
34+
: "github-light"
35+
36+
const message = {
37+
type: "set-theme",
38+
theme: newTheme,
39+
}
40+
iframe.contentWindow.postMessage(message, "https://utteranc.es")
41+
}
42+
}
43+
44+
// 테마 변경 감지를 위한 MutationObserver
45+
const observer = new MutationObserver(handleThemeChange)
46+
observer.observe(document.documentElement, {
47+
attributes: true,
48+
attributeFilter: ["class"],
49+
})
50+
51+
return () => {
52+
observer.disconnect()
53+
}
54+
}, [])
55+
56+
return (
57+
<div className="mt-16 pt-8 border-t">
58+
<h3 className="text-xl font-semibold mb-6">댓글</h3>
59+
<div ref={commentsRef} className="utterances-container" />
60+
</div>
61+
)
62+
}
63+
64+
export default Utterances

src/style.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,15 @@
265265
@apply bg-muted/30;
266266
}
267267

268+
/* Utterances 댓글 스타일링 */
269+
.utterances-container {
270+
@apply max-w-none;
271+
}
272+
273+
.utterances {
274+
@apply max-w-none;
275+
}
276+
268277
/* 다크 모드 스타일 */
269278
.dark .markdown-content {
270279
@apply text-foreground;

src/templates/blog-post.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Layout from "@/components/layout"
66
import Seo from "@/components/seo"
77
import CategoryTag from "@/components/category-tag"
88
import { ChevronLeft, ChevronRight, Calendar } from "lucide-react"
9+
import Utterances from "@/components/utterances"
910

1011
interface BlogPostTemplateProps {
1112
data: {
@@ -113,6 +114,9 @@ const BlogPostTemplate: React.FC<BlogPostTemplateProps> = ({
113114
<Bio />
114115
</div>
115116

117+
{/* 댓글 */}
118+
<Utterances />
119+
116120
{/* 이전/다음 포스트 네비게이션 */}
117121
<nav className="mt-16">
118122
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">

0 commit comments

Comments
 (0)