仓库是公开的,否则访客将无法查看 discussion
giscus app 已安装,否则访客将无法评论和回应,安装后的结果如下
仓库的 discussions 功能已启用,否则访客将无法评论和回应
填写仓库:
,例如: owner/repo
huchaomin/vitepress
页面 与 discussion 映射关系,勾选 pathname, 建议勾选'使用严格的标题匹配'
discussion 分类 按照推荐选择 announcements
只搜索该分类中的 discussion 建议勾选
特性建议全部勾上
然后你就在 '启用 giscus' 下面看到你的配置了
pnpm add @giscus/vue
<!--
* @Author : huchaomin iisa_peter@163.com
* @Date : 2024-12-18 09:56:13
* @LastEditors : huchaomin iisa_peter@163.com
* @LastEditTime : 2025-01-01 11:44:54
* @Description :
-->
<script setup lang="ts">
import Giscus from '@giscus/vue'
import { inBrowser, useData } from 'vitepress'
const { frontmatter, isDark } = useData()
const isProd = !import.meta.env.PROD
const showCommentInfoState = reactive({
inView: false,
notFound: false,
})
watch(
() => frontmatter.value.uuid,
() => {
showCommentInfoState.inView = false
showCommentInfoState.notFound = false
},
)
watchEffect(() => {
if (showCommentInfoState.inView && showCommentInfoState.notFound) {
$msg.info('暂无评论,可占一楼进行评论')
}
})
interface IErrorMessage {
error: string
}
function handleMessage(event: MessageEvent) {
if (
event.origin !== 'https://giscus.app' ||
!(typeof event.data === 'object' && event.data.giscus) ||
!isProd
) {
return
}
const giscusData = event.data.giscus
if ('error' in giscusData) {
const errorMessage: IErrorMessage = giscusData
if (errorMessage.error === 'Discussion not found') {
showCommentInfoState.notFound = true
}
}
}
if (inBrowser) {
window.addEventListener('message', handleMessage)
onUnmounted(() => {
window.removeEventListener('message', handleMessage)
})
}
const rootRef = ref<HTMLDivElement | null>(null)
useIntersectionObserver(
rootRef,
([entry]) => {
if (entry.isIntersecting) {
showCommentInfoState.inView = true
}
},
{
threshold: 0.5,
},
)
const theme = computed(() => (isDark.value ? 'dark_tritanopia' : 'light_tritanopia'))
</script>
<template>
<div ref="rootRef">
<ClientOnly>
<Giscus
v-if="frontmatter.uuid && isProd"
:key="frontmatter.uuid"
repo="huchaomin/vitepress-note"
repo-id="R_kgDOMZ-wiw"
category="Announcements"
category-id="DIC_kwDOMZ-wi84ClUQt"
mapping="og:title"
strict="1"
reactions-enabled="1"
emit-metadata="1"
input-position="top"
:theme="theme"
lang="zh-CN"
loading="lazy"
crossorigin="anonymous"
async
></Giscus>
</ClientOnly>
</div>
</template>
mapping:'og:title'
因为我把我的页面的 uuid 作为 og:title 的 content 传给了 giscus,这样就可以在 giscus 中通过 og:title 来查找对应的 discussion
// enhanceApp 方法里面
router.onAfterRouteChanged = (to: string) => {
if (inBrowser) {
const uuid = router.route.data.frontmatter.uuid as string | undefined
if (uuid) {
let meta = document.querySelector('meta[property="og:title"]')
if (!meta) {
meta = document.createElement('meta')
meta.setAttribute('property', 'og:title')
document.head.appendChild(meta)
}
meta.setAttribute('content', uuid)
}
}
}
推荐大家也这样做,第六步其他选项 pathname、URL、title 大部分情况下没有问题
但如果你想给你的博客页面移动一下位置,导致你的url变了,那么你的评论就找不到了。
上一篇:添加gitalk评论 也有这个问题,至于怎么生成 uuid, 可以看这个博客的源码,写的不好可以使用这个评论喷我
og:title
不能这么写function transformHead({ pageData }) {
const uuid = pageData.frontmatter.uuid as string | undefined
if (uuid) {
return [
[
'meta',
{
content: uuid,
property: 'oa:title',
},
],
]
}
}
这样写是不行的,因为这个函数只会在页面加载的时候执行一次,而不会在页面切换的时候执行,所以不会动态更新
的值og:title