Skip to content

Commit cf4613d

Browse files
committed
feat: 댓글 기능을 Utterance 에서 Giscus 로 변경
1 parent 63c045a commit cf4613d

6 files changed

Lines changed: 121 additions & 65 deletions

File tree

.vitepress/theme/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { h } from "vue";
33
import type { Theme } from "vitepress";
44
import DefaultTheme from "vitepress/theme";
5+
import Giscus from "@giscus/vue";
56
import PostCardList from "@/components/PostCardList/PostCardList.vue";
67
import PostLayout from "@/components/PostLayout/PostLayout.vue";
78
import "./style.css";
@@ -11,5 +12,6 @@ export default {
1112
Layout: PostLayout,
1213
enhanceApp({ app, router, siteData }) {
1314
app.component("PostCardList", PostCardList);
15+
app.component("Giscus", Giscus);
1416
},
1517
} satisfies Theme;

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@
1010
"editor.snippetSuggestions": "top",
1111
"github.copilot.enable": {
1212
"markdown": true
13-
}
13+
},
14+
"cSpell.words": ["Giscus", "toothlessdev"]
1415
}

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,8 @@
1212
"gray-matter": "^4.0.3",
1313
"prettier": "^3.6.2",
1414
"vitepress": "^1.6.4"
15+
},
16+
"dependencies": {
17+
"@giscus/vue": "^3.1.1"
1518
}
1619
}
Lines changed: 54 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,62 @@
11
<script setup lang="ts">
2-
import { onMounted, onBeforeUnmount, watch, ref, nextTick, toRef, type Ref } from "vue";
3-
4-
const COMMENT_REPOSITORY = "toothlessdev/toothlessdev.github.io";
5-
6-
const props = defineProps<{
7-
theme: string;
8-
}>();
9-
10-
const containerRef = ref<HTMLDivElement | null>(null);
11-
12-
function mountUtterances(theme: string) {
13-
const container = containerRef.value;
14-
15-
if (!container) return;
16-
if (container.querySelector("iframe.utterances-frame")) return;
17-
18-
const script = document.createElement("script");
19-
20-
script.src = "https://utteranc.es/client.js";
21-
script.async = true;
22-
script.crossOrigin = "anonymous";
2+
import { computed } from "vue";
3+
import { useData } from "vitepress";
4+
import Giscus from "@giscus/vue";
5+
6+
const GISCUS = {
7+
repo: "toothlessdev/toothlessdev.github.io",
8+
repoId: "R_kgDOK8A2Yg",
9+
category: "General",
10+
categoryId: "DIC_kwDOK8A2Ys4Cv8uz",
11+
} as const;
12+
13+
const { isDark, lang } = useData();
14+
15+
const theme = computed(() => (isDark.value ? "dark" : "light"));
16+
const mapping = "pathname";
17+
const uiLang = computed(() => (lang.value?.startsWith("ko") ? "ko" : "en"));
18+
</script>
2319

24-
script.setAttribute("repo", COMMENT_REPOSITORY);
25-
script.setAttribute("issue-term", "pathname");
26-
script.setAttribute("label", "blog-comment");
27-
script.setAttribute("theme", theme);
20+
<template>
21+
<div class="giscus-comments">
22+
<Giscus
23+
class="giscus"
24+
:repo="GISCUS.repo"
25+
:repo-id="GISCUS.repoId"
26+
:category="GISCUS.category"
27+
:category-id="GISCUS.categoryId"
28+
:mapping="mapping"
29+
strict="0"
30+
reactions-enabled="1"
31+
emit-metadata="0"
32+
input-position="top"
33+
:theme="theme"
34+
:lang="uiLang"
35+
crossorigin="anonymous"
36+
loading="lazy"
37+
/>
38+
</div>
39+
</template>
2840

29-
container.appendChild(script);
41+
<style scoped>
42+
.giscus-comments {
43+
margin-top: 4rem;
44+
padding-top: 1rem;
45+
border-top: 1px solid var(--vp-c-divider);
3046
}
3147
32-
function setUtterancesTheme(theme: string) {
33-
const iframe = containerRef.value?.querySelector<HTMLIFrameElement>("iframe.utterances-frame");
34-
if (!iframe?.contentWindow) return;
35-
iframe.contentWindow.postMessage({ type: "set-theme", theme }, "https://utteranc.es");
48+
.giscus-comments :deep(.giscus),
49+
.giscus-comments :deep(iframe) {
50+
margin-top: 0;
3651
}
52+
</style>
3753

38-
onMounted(async () => {
39-
await nextTick();
40-
mountUtterances(props.theme);
41-
});
42-
43-
watch(toRef(props, "theme"), (theme) => {
44-
if (!containerRef.value?.querySelector("iframe.utterances-frame")) {
45-
mountUtterances(theme);
46-
return;
47-
}
48-
setUtterancesTheme(theme);
49-
});
50-
51-
onBeforeUnmount(() => {
52-
const container = containerRef.value;
53-
if (!container) return;
54-
55-
container.querySelector("iframe.utterances-frame")?.remove();
56-
});
57-
</script>
54+
<style>
55+
.giscus-frame {
56+
margin-top: 2rem;
57+
}
5858
59-
<template>
60-
<div ref="containerRef" />
61-
</template>
59+
.giscus {
60+
margin-top: 2rem;
61+
}
62+
</style>
Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,19 @@
11
<script setup>
2-
import { computed } from "vue";
32
import { useData } from "vitepress";
43
import DefaultTheme from "vitepress/theme";
54
import PostComment from "@/components/PostComment/PostComment.vue";
65
const { Layout } = DefaultTheme;
76
8-
const COMMENT_THEME_DARK = "photon-dark";
9-
const COMMENT_THEME_LIGHT = "github-light";
7+
const { frontmatter } = useData();
108
11-
const { frontmatter, page, isDark } = useData();
12-
13-
const commentTheme = computed(() => (isDark.value ? COMMENT_THEME_DARK : COMMENT_THEME_LIGHT));
9+
// comments가 false가 아닌 경우 댓글을 표시 (기본값은 true)
10+
const showComments = frontmatter.value.comments !== false;
1411
</script>
1512

1613
<template>
1714
<Layout>
1815
<template #doc-after>
19-
<PostComment
20-
v-if="frontmatter.comment"
21-
:key="page.relativePath"
22-
:theme="commentTheme"
23-
></PostComment>
16+
<PostComment v-if="showComments" />
2417
</template>
2518
</Layout>
2619
</template>

yarn.lock

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,13 @@
318318
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c"
319319
integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==
320320

321+
"@giscus/vue@^3.1.1":
322+
version "3.1.1"
323+
resolved "https://registry.yarnpkg.com/@giscus/vue/-/vue-3.1.1.tgz#c47021f42b7e7951f2fb6149f93a0756db226b80"
324+
integrity sha512-xgsc93MibRQ0d1glBxN1BrEREHTIf3BPYs/3R+UZHNqawFFoWBV6iJ7uVCXMqoEKZdE2c78B3aKt5gfGqo8I5A==
325+
dependencies:
326+
giscus "^1.6.0"
327+
321328
"@iconify-json/simple-icons@^1.2.21":
322329
version "1.2.52"
323330
resolved "https://registry.yarnpkg.com/@iconify-json/simple-icons/-/simple-icons-1.2.52.tgz#0e4d1dc7e70a96ac52709efe309e12c0be1bf23d"
@@ -359,6 +366,18 @@
359366
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba"
360367
integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==
361368

369+
"@lit-labs/ssr-dom-shim@^1.4.0":
370+
version "1.4.0"
371+
resolved "https://registry.yarnpkg.com/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.4.0.tgz#55eb80ab5ef6e188f7e541c1e2bea1ef582413b8"
372+
integrity sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==
373+
374+
"@lit/reactive-element@^2.1.0":
375+
version "2.1.1"
376+
resolved "https://registry.yarnpkg.com/@lit/reactive-element/-/reactive-element-2.1.1.tgz#0662ac4a43d4898974aef9a6c5cd47b9e331919a"
377+
integrity sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==
378+
dependencies:
379+
"@lit-labs/ssr-dom-shim" "^1.4.0"
380+
362381
"@nodelib/fs.scandir@2.1.5":
363382
version "2.1.5"
364383
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
@@ -598,6 +617,11 @@
598617
dependencies:
599618
undici-types "~7.12.0"
600619

620+
"@types/trusted-types@^2.0.2":
621+
version "2.0.7"
622+
resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11"
623+
integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==
624+
601625
"@types/unist@*", "@types/unist@^3.0.0":
602626
version "3.0.3"
603627
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.3.tgz#acaab0f919ce69cce629c2d4ed2eb4adc1b6c20c"
@@ -998,6 +1022,13 @@ fsevents@~2.3.2, fsevents@~2.3.3:
9981022
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
9991023
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
10001024

1025+
giscus@^1.6.0:
1026+
version "1.6.0"
1027+
resolved "https://registry.yarnpkg.com/giscus/-/giscus-1.6.0.tgz#96c592e01829707b3a0ba72c2636c07a28b5c19d"
1028+
integrity sha512-Zrsi8r4t1LVW950keaWcsURuZUQwUaMKjvJgTCY125vkW6OiEBkatE7ScJDbpqKHdZwb///7FVC21SE3iFK3PQ==
1029+
dependencies:
1030+
lit "^3.2.1"
1031+
10011032
glob-parent@^5.1.2:
10021033
version "5.1.2"
10031034
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
@@ -1118,6 +1149,31 @@ kind-of@^6.0.0, kind-of@^6.0.2:
11181149
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
11191150
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
11201151

1152+
lit-element@^4.2.0:
1153+
version "4.2.1"
1154+
resolved "https://registry.yarnpkg.com/lit-element/-/lit-element-4.2.1.tgz#0a3782f36eaa545862fe07f84abcb14b2903a042"
1155+
integrity sha512-WGAWRGzirAgyphK2urmYOV72tlvnxw7YfyLDgQ+OZnM9vQQBQnumQ7jUJe6unEzwGU3ahFOjuz1iz1jjrpCPuw==
1156+
dependencies:
1157+
"@lit-labs/ssr-dom-shim" "^1.4.0"
1158+
"@lit/reactive-element" "^2.1.0"
1159+
lit-html "^3.3.0"
1160+
1161+
lit-html@^3.3.0:
1162+
version "3.3.1"
1163+
resolved "https://registry.yarnpkg.com/lit-html/-/lit-html-3.3.1.tgz#f0a7e4b9ea0a1d034eb28a4bf2d1b0a0096253e3"
1164+
integrity sha512-S9hbyDu/vs1qNrithiNyeyv64c9yqiW9l+DBgI18fL+MTvOtWoFR0FWiyq1TxaYef5wNlpEmzlXoBlZEO+WjoA==
1165+
dependencies:
1166+
"@types/trusted-types" "^2.0.2"
1167+
1168+
lit@^3.2.1:
1169+
version "3.3.1"
1170+
resolved "https://registry.yarnpkg.com/lit/-/lit-3.3.1.tgz#9dc79be626bc9a3b824de98b107dd662cabdeda6"
1171+
integrity sha512-Ksr/8L3PTapbdXJCk+EJVB78jDodUMaP54gD24W186zGRARvwrsPfS60wae/SSCTCNZVPd1chXqio1qHQmu4NA==
1172+
dependencies:
1173+
"@lit/reactive-element" "^2.1.0"
1174+
lit-element "^4.2.0"
1175+
lit-html "^3.3.0"
1176+
11211177
lru-cache@^11.0.0:
11221178
version "11.2.1"
11231179
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.2.1.tgz#d426ac471521729c6c1acda5f7a633eadaa28db2"

0 commit comments

Comments
 (0)