FIND YOUR NEXT READ

找一篇,想读的文章。

输入关键词,发现藏在文字里的答案。

Astro 博客接入 Twikoo 评论系统:EdgeOne Makers 部署到前端懒加载全流程

Astro 博客接入 Twikoo 评论系统:EdgeOne Makers 部署到前端懒加载全流程

目录

为什么选 Twikoo

静态博客最大的痛点之一就是没有评论区。GitHub 上评论方案不少,最后我选了 Twikoo,原因很直接:

  • 零成本:EdgeOne Makers 免费额度对个人博客完全够跑
  • 不用买服务器:网页控制台拖个 ZIP 就部署完,数据库自动提供
  • 前端集成简单:一个 JS 文件 + 几行初始化代码
  • 功能齐全:表情贴图、邮件通知、管理员后台、评论审核都有

下面是我从 EdgeOne Makers 部署到 Astro 前端懒加载集成的完整踩坑过程。

整体架构

先看清楚整个评论系统是怎么跑起来的:

Twikoo 评论系统架构图

访客在你的博客文章页输入评论 → Twikoo 前端 JS 把数据发到 EdgeOne Makers 上的云函数 → 云函数把评论存进平台自动提供的 KV 存储 → 你在 Twikoo 管理后台审核和回复。

整个链路里,你只需要管两个东西:EdgeOne Makers 上的 Twikoo 项目(后端) 和 博客页面里的一段初始化代码(前端)。

第一步:下载 Twikoo EdgeOne 部署包

  1. 去 Twikoo 官方文档 下载 twikoo-edgeone-makers.zip
  2. 不要解压,这个 ZIP 直接用于下一步上传

这个包只有三个文件(函数入口、SMTP 桥接源码、依赖声明),云函数实现由平台从 npm 上自动取回,后续升级只需在项目里点「重新部署」。

第二步:上传到 EdgeOne Makers

  1. 进入 EdgeOne Makers 控制台,在「项目」标签页点击直接上传
  2. 填写项目名称(比如 twikoo,仅小写字母、数字和连字符)
  3. 选择加速区域(选「全球可用区(含中国大陆)」)
  4. 把刚才下载的 ZIP 拖入上传区域,点击开始部署
  5. 等待状态变为成功

评论数据存放在平台自动提供的 Blob KV 中,首次写入时自动创建命名空间,不需要任何额外配置,也不用自备数据库。

腾讯EdgeOne Makers控制台

腾讯EdgeOne Makers上传项目

第三步:修改 Node.js 版本(关键!)

部署完后,有一个必改项:

  1. 进入项目的项目设置
  2. 把 Node.js 版本改为 24.18.0 并保存
  3. 回到构建部署页点一次重新部署

为什么要改? 平台默认的 Node.js 版本偏低,Twikoo 2.0 的产物和依赖要求 Node 24+,不改的话函数会跑不起来。

修改nodejs环境变量

第四步:绑定自定义域名

EdgeOne Makers 的默认域名(*.edgeone.cool)只有 3 小时预览有效期,必须绑自己的域名才能长期使用。

  1. 进入项目的域名管理页,点击添加自定义域名
  2. 输入你的子域名(比如 twikoo.yourblog.com),环境选生产
  3. 等待状态变为「请添加 CNAME」,复制页面上的 CNAME 值
  4. 到你的 DNS 服务商(比如腾讯云 DNSPod、阿里云),为该域名添加一条 CNAME 记录
  5. 回到域名管理页,点击 HTTPS 配置 → 选择申请免费证书 → 自动验证 → 保存
  6. 等待状态变为已生效

绑好后,浏览器访问 https://twikoo.yourblog.com/,应该看到「Twikoo 云函数运行正常,请参考…」,这个地址(含 https://,不带路径)就是前端的 envId。

绑定域名

访问自定义域名

注意:envId 是域名根目录,不是某个子路径。因为部署包把云函数映射到了根路径 /。

第五步:验证后端并设置管理员

  1. 浏览器访问 https://twikoo.yourblog.com/,看到正常提示即部署成功
  2. 打开 Twikoo 管理后台:https://twikoo.js.org/admin.html
  3. 输入你的 envId,第一次登录会让你设置管理员密码,记好

第六步:Astro 前端集成

这一步是重点。网上大部分教程都是直接引入 Twikoo JS 然后初始化,但这样会在每个页面都加载评论脚本,影响博客首页速度。我做了懒加载处理:只有进入文章详情页时才动态加载评论脚本。

6.1 配置项

先在 src/config.ts 里加配置:

// src/config.ts
const config = {
  // ... 其他配置
  Comment: {
    Twikoo: {
      enable: true,
      envId: 'https://twikoo.yourblog.com', // 你的自定义域名
      script: 'https://cdn.jsdelivr.net/npm/twikoo@2.0.15/dist/twikoo.nocss.js',
      style: 'https://cdn.jsdelivr.net/npm/twikoo@2.0.15/dist/twikoo.css',
    }
  },
}

6.2 文章页嵌入评论容器

在 src/pages/posts/[slug].astro 的文章末尾,加评论区的 HTML 结构:

---
<Base title={post.title} commentStyles={true}>
  <!-- ... 文章内容 ... -->

  {config.Comment.Twikoo.enable && (
    <section class="entry-comments" id="comments">
      <h3>
        <span class="comment-heading-icon">●</span> 评论
        <span class="comment-heading-count" id="comment-count">0</span>
      </h3>

      <!-- 加载中状态 -->
      <div class="comment-loading" id="comment-loading">
        <span class="comment-loading-spinner"></span>
        <span>评论加载中…</span>
      </div>

      <!-- Twikoo 挂载点,默认隐藏,脚本加载完成后再显示 -->
      <div id="tcomment"
           data-env-id={config.Comment.Twikoo.envId}
           data-script={config.Comment.Twikoo.script}
           hidden>
      </div>
    </section>
  )}
</Base>

6.3 懒加载初始化脚本

关键在这一段:评论脚本不是页面一打开就加载,而是等到用户进入文章页、Twikoo 的 DOM 挂载点存在时才动态插入 <script> 标签。同时处理了加载失败、表单渲染等待、评论数统计等边界情况。

<script>
  let twikooScript: Promise<void> | undefined;

  document.addEventListener('astro:page-load', () => {
    const mount = document.getElementById('tcomment');
    if (!mount) return;

    const envId = mount.dataset.envId || '';
    const loading = document.getElementById('comment-loading');

    // 显示评论表单:Twikoo 渲染是异步的,用 MutationObserver 等表单出现
    let formObserver: MutationObserver | undefined;
    const showForm = () => {
      if (!mount.querySelector('.tk-submit textarea.tk-textarea__inner')) return;
      formObserver?.disconnect();
      mount.hidden = false;
      if (loading) loading.hidden = true;
    };

    // 加载失败处理
    const showError = () => {
      formObserver?.disconnect();
      if (loading) loading.hidden = true;
      mount.hidden = false;
      mount.textContent = '评论加载失败,请刷新页面重试。';
    };

    // 只在第一次时加载 Twikoo 脚本,后续页面切换复用
    if (!twikooScript) {
      twikooScript = (window as any).twikoo
        ? Promise.resolve()
        : new Promise((resolve, reject) => {
            const script = document.createElement('script');
            script.src = mount.dataset.script || '';
            script.async = true;
            script.onload = () => resolve();
            script.onerror = () => reject(new Error('评论脚本加载失败'));
            document.body.appendChild(script);
          });
    }

    twikooScript.then(() => {
      mount.replaceChildren();
      formObserver = new MutationObserver(() => showForm());
      formObserver.observe(mount, { childList: true, subtree: true });

      // 初始化 Twikoo
      Promise.resolve((window as any).twikoo!.init({
        envId,
        el: '#tcomment',
        path: location.pathname,
        onCommentLoaded: () => showForm(),
      })).then(() => showForm(true)).catch(showError);

      // 单独拉取评论数,显示在标题旁边
      (window as any).twikoo!.getCommentsCount({
        envId,
        urls: [location.pathname],
        includeReply: true,
      }).then((items: Array<{ count: number }>) => {
        const count = document.getElementById('comment-count');
        if (count) count.textContent = String(items[0]?.count ?? 0);
      }).catch(() => {});

    }).catch(() => {
      twikooScript = undefined;
      showError();
    });
  });
</script>

为什么这么写?

  • twikooScript 用了模块级变量缓存,博客站内切换文章页时不会重复加载脚本
  • astro:page-load 事件是 Astro 视图过渡的标准钩子,SPA 切换页面时会重新触发
  • path: location.pathname 保证每篇文章的评论是独立的,不会串

最终效果

部署完之后,文章页底部就是这样的:

评论区效果

评论数会显示在「评论」标题旁边,加载过程中有 loading 动画,加载失败有提示,整个过程不阻塞页面渲染。

常见问题

Q:EdgeOne Makers 免费吗? A:个人项目免费额度内够用。评论数据存在平台 KV 里,不用自己买数据库。

Q:为什么我部署完访问域名一直 401? A:默认的 *.edgeone.cool 域名只有 3 小时预览有效,必须绑自定义域名才能长期访问。

Q:为什么函数跑不起来 / 报错? A:检查项目设置里的 Node.js 版本是不是 24.18.0,改完要重新部署。

Q:评论会被垃圾评论刷爆吗? A:Twikoo 后台可以设置评论默认隐藏,审核通过才显示。注意 EdgeOne 版不支持 Akismet 垃圾评论检测。

Q:邮件通知能用吗? A:可以,但 EdgeOne 函数运行时不支持直连 SMTP,需要用 SendGrid、MailChannels,或者用部署包自带的 SMTP 桥接(在环境变量里配 TWIKOO_SMTP_BRIDGE_TOKEN)。

Q:想换评论系统怎么办? A:Twikoo 管理后台支持导出评论数据,可以迁移。


整个部署过程从下载 ZIP 到绑定域名,快的话 20 分钟搞定。后端就是拖个文件上传,真正花时间的是前端怎么优雅地加载评论脚本,不拖慢博客主页面的速度。

ⓘ 本作品保留所有权利,未经授权请勿转载。
返回首页
上一篇MacOs利用Brew安装Jdk11

评论 0

评论加载中…