npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

hexo-generator-webmention

v1.0.1

Published

A Hexo generator plugin to fetch and inject Webmention data (via IFTTT Webhooks) into your site's template variables, allowing you to display comments, likes, and reposts from across the web.

Readme

English Document

hexo-generator-webmention

为您的 Hexo 网站提供 Webmention 支持,包括接收、缓存和显示功能。

安装

npm install hexo-generator-webmention --save

配置

在您站点的 _config.yml 文件中添加以下配置:

webmention:
  enable: true
  debug: false
  domain: your-domain.com  # 替换为您的域名
  token: your_webmention_io_token # 替换为您的 webmention.io API Token
  mode: static # 显示模式: static, dynamic, 或 hybrid
  • enable: true | false - 插件总开关。
  • debug: true | false - 在控制台输出详细的调试信息。
  • domain: string - 您在 webmention.io 上注册的域名。
  • token: string - 您在 webmention.io 的 API Token。
  • mode: static | dynamic | hybrid - Webmentions 的显示模式(详见下文)。

使用方法

在您的主题模板文件(例如 post.ejspage.ejs)中,您想要显示 Webmentions 的地方,添加以下助手函数:

<%- render_webmentions() %>

插件会在每次生成网站时,从 webmention.io 获取新的 Webmentions,并将它们缓存到项目根目录下的 .webmentions-cache.json 文件中。

显示模式

本插件支持三种显示 Webmentions 的模式,通过 mode 配置项进行切换。

1. static (默认)

  • 工作方式: 在 hexo generate 时,所有 Webmentions 会被直接渲染成静态 HTML。
  • 优点: 无需客户端 JavaScript,加载速度快,对 SEO 友好。
  • 缺点: 只有在下次生成网站时才会显示新的 Webmentions。

2. dynamic

  • 工作方式: 服务端只生成一个空的 <div> 容器。页面加载后,由客户端 JavaScript 异步请求并渲染所有的 Webmentions。
  • 优点: 总是显示最新的 Webmentions,无需重新生成网站。
  • 缺点: 依赖客户端 JavaScript,对 SEO 不友好,在 JavaScript 被禁用时无法显示。

3. hybrid

  • 工作方式: 结合了 staticdynamic 的优点。在 hexo generate 时,已缓存的 Webmentions 会被渲染成静态 HTML。页面加载后,客户端 JavaScript 会异步获取最新的 Webmentions 并追加到列表末尾。
  • 优点: 首次加载速度快,对 SEO 友好,同时也能动态展示最新的 Webmentions。
  • 这是推荐的模式。

如何启用 dynamichybrid 模式

要使用 dynamichybrid 模式,您需要手动将本插件提供的客户端脚本集成到您的主题中:

  1. 复制脚本: 将位于 node_modules/hexo-generator-webmention/source/js/webmention-dynamic.js 的文件复制到您主题的 source/js/ 目录下。

  2. 在主题中引用脚本: 在您主题的布局文件(例如 layout.ejs, head.ejsfooter.ejs)中,添加以下 <script> 标签:

    <!-- 建议放在 </body> 标签前 -->
    <script src="/js/webmention-dynamic.js" async></script>

完成以上步骤后,将 _config.yml 中的 mode 设置为 dynamichybrid 即可生效。

样式和自定义

本插件只负责生成结构化的 HTML,不包含任何内联样式。你需要根据自己的主题风格,为 Webmentions 添加 CSS 样式。

HTML 结构和 CSS 类

插件生成的 HTML 结构大致如下,您可以针对这些类编写样式:

<div class="webmention-section" data-mode="static">
  <h3 class="webmention-title">Webmentions (<span class="webmention-count">...</span>)</h3>
  <div class="webmention-list">
    <div class="webmention-item" id="webmention-...">
      <div class="webmention-author">
        <img class="webmention-author-photo" src="...">
        <a class="webmention-author-name" href="...">...</a>
        <span class="webmention-date">...</span>
      </div>
      <div class="webmention-content">
        ...
      </div>
      <div class="webmention-meta">
        <a class="webmention-source" href="...">查看原文</a>
      </div>
    </div>
    <!-- more items -->
  </div>
</div>

示例 CSS

你可以将以下 CSS 代码复制到你主题的样式表(例如 themes/主题/source/css/main.css)中,并根据需要进行修改,以作为基础样式:

/* Webmention 区域总容器 */
.webmention-section {
  margin-top: 3em;
}

/* 标题 */
.webmention-title {
  font-size: 1.5em;
  margin-bottom: 1em;
  border-bottom: 1px solid #eee;
  padding-bottom: 0.5em;
}

/* 列表 */
.webmention-list {
  padding: 0;
  margin: 0;
}

/* 单个 Webmention 项目 */
.webmention-item {
  list-style: none;
  margin-top: 1.5em;
  padding-top: 1.5em;
  border-top: 1px solid #eee;
}

.webmention-item:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}

/* 作者信息栏 */
.webmention-author {
  display: flex;
  align-items: center;
  font-size: 0.9em;
}

/* 作者头像 */
.webmention-author-photo {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  margin-right: 12px;
}

/* 作者名字 */
.webmention-author-name {
  font-weight: bold;
  color: #333;
  text-decoration: none;
}

.webmention-author-name:hover {
  text-decoration: underline;
}

/* 日期 */
.webmention-date {
  margin-left: auto;
  font-size: 0.9em;
  color: #888;
}

/* 内容 */
.webmention-content {
  margin: 1em 0;
  line-height: 1.6;
}

.webmention-content p {
  margin: 0.5em 0;
}

/* 元信息(如“查看原文”) */
.webmention-meta {
  font-size: 0.8em;
  text-align: right;
}

.webmention-source {
  color: #888;
  text-decoration: none;
}

.webmention-source:hover {
  text-decoration: underline;
}

/* 动态加载时的动画效果 */
.webmention-dynamic {
  animation: webmention-fade-in 0.5s ease;
}

@keyframes webmention-fade-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}