爱意满满的作品展示区。
nicooolas

想做一个更轻的「友链网络」组件: LinkPals

  •  
  •   nicooolas · 1 day ago · 626 views

    大家好,我最近在做一个小产品,叫 LinkPals。它想解决的不是一个很宏大的问题,而是一个在独立站、博客、个人项目里很常见但一直有点尴尬的小问题:友链怎么做,才既真的有用,又不把每个网站的 footer 变成一堵链接墙。

    一句话介绍:LinkPals 是一个给小型网站圈子用的友链组件。几个网站共用一份 friends.json,每个站点只嵌入一段 JS ,页面上默认只展示 4 到 8 个精选链接,完整网络则放在抽屉或 /friends 页面里。

    我先把 demo 和代码结构做出来了,目前还是早期版本,所以更想听听大家对这个方向的判断。

    为什么想做这个

    友链其实是老互联网里一个很有温度的东西。

    以前逛博客,经常会从一个作者的链接页跳到另一个站,慢慢摸到一小片人的网络。相比搜索引擎和信息流,这种发现方式很慢,但也很有上下文:你知道这个链接不是算法随机推给你的,而是某个站长真的愿意放在自己页面上的。

    但现在再给网站加友链,会遇到几个现实问题:

    1. 如果每个站都放完整列表,footer 很快会失控。
    2. 如果只放几个链接,又很难保持公平,后续也不好维护。
    3. 如果每个站单独维护一份 HTML ,更新一次要改很多地方。
    4. 如果做成 SaaS ,又显得太重。友链这件事本来就不应该要求账号、后台、复杂权限。

    所以我想做的不是一个「友情链接管理系统」,而是一个更小的东西:给一个小圈子一份中心清单,再让每个站点用很轻的方式消费它。

    LinkPals 的基本思路

    LinkPals 的核心是三个层次:

    第一层是共享数据源。

    一个圈子维护一份公开 JSON ,比如里面有站点标题、URL 、描述、分类、标签、权重、是否精选、强调色等字段。早期版本里,public/friends.json 就是最简单的 source of truth 。后面也加了发布流程,可以把列表发布成稳定的公开地址,并用私密 update key 以后继续更新。

    第二层是嵌入组件。

    参与站点只需要放一段脚本。脚本会读取共享 JSON ,渲染出页脚友链区。它不会依赖 React/Vue ,也不要求站点本身用 Astro 。静态 HTML 、WordPress 、Astro 、React 、Vue 项目理论上都可以用。

    第三层是完整网络入口。

    默认 footer 不展示全部链接,只展示少量精选或相关站点。用户想继续逛,可以打开抽屉,或者进入完整 /friends 页面。这样首页保持克制,但友链网络并没有被藏起来。

    我觉得它的价值点

    1. 让小网站之间的推荐更容易持续

    很多友链页面一开始很认真,后来没人维护。LinkPals 想把维护成本降到一个地方:改一次清单,所有接入站点都能拿到新版本。

    这对小型创作者圈子、独立产品矩阵、newsletter 互推、几个朋友共同维护的网站群,可能会比较合适。

    2. 不把「展示全部」当成默认正确

    友链不是越多越好。一个页面上出现 50 个链接,访客其实很难判断从哪里开始点。

    所以 LinkPals 默认只展示少量链接。它会根据当前站点、标签、分类、权重、是否 featured 等信息做一个简单排序,把最可能相关的链接放在 footer 。完整列表仍然可访问,只是从默认视图里挪开。

    这个取舍有点像:首页负责推荐,目录页负责完整。

    3. 对参与站点足够轻

    我不想让每个参与者都注册账号、装插件、维护后台。最理想的接入方式应该是:

    <script
      src="https://your-domain.example/friends.js"
      data-src="https://your-domain.example/friends.json"
      data-current="your-site-id"
      defer
    ></script>
    

    这里的 data-current 用来告诉组件当前站点是谁,这样它可以避免推荐用户正在看的站点,也可以按相关性展示朋友站点。

    4. 对搜索引擎和普通访客都是真链接

    渲染后,精选链接是实际的 <a href>。我不想把它做成纯 canvas 、iframe ,或者必须由某个大而重的客户端框架接管的东西。

    这个点不神奇,但对友链很重要:链接应该就是链接。

    技术上目前怎么做

    项目是 Astro 做产品页和 demo ,widget runtime 放在 src/widget,单独编译成 public/friends.js

    一些目前的技术选择:

    1. Widget 不依赖框架

    嵌入脚本是 dependency-free TypeScript 编译出来的。原因很简单:接入方的网站环境不可控。

    有些是 Astro ,有些是 WordPress ,有些是手写静态页,有些可能已经有 React/Vue 。如果为了一个 footer 友链再引入一套框架,感觉有点过。

    2. 用 Shadow DOM 做样式隔离

    友链组件会被放进各种各样的网站里,CSS 冲突是迟早的事。Shadow DOM 可以让组件样式尽量不污染宿主页面,也不被宿主页面轻易打乱。

    同时我也留了 accent color 一类配置,让组件可以稍微贴近当前站点视觉,而不是完全像一个外来的广告块。

    3. 排序逻辑保持可解释

    目前的 featured 排序不是黑盒算法,主要看:

    • 是否手动 featured
    • 站点权重
    • 是否与当前站点相关
    • 标签重合
    • 分类是否一致
    • 一个稳定的小 jitter ,避免同分时永远一样

    我更倾向于让站长能理解和调整,而不是做一个看起来很聪明、实际不可控的推荐系统。

    4. 数据格式先用 JSON

    friends.json 的 v1 格式比较直白:

    {
      "version": 1,
      "title": "Friends",
      "description": "A curated list of independent sites.",
      "sites": [
        {
          "id": "example-site",
          "title": "Example Site",
          "url": "https://example.com",
          "description": "A small independent website.",
          "tags": ["Writing", "Tools"],
          "category": "Knowledge",
          "featured": true,
          "weight": 10
        }
      ]
    }
    

    JSON 的好处是简单、可复制、可托管,也方便以后迁移。即使不用 LinkPals 的托管发布流程,一个人也可以自己维护这个文件。

    5. 发布服务尽量克制

    目前有一个 Cloudflare Worker 方向的实现:可以粘贴 URL ,服务端抓取页面 metadata ,生成初始站点信息;发布后得到公开 JSON 地址和 update key 。之后用 update key 更新同一份列表。

    这里我刻意没有上账号系统。因为 v1 的目标不是做完整 CMS ,而是让「一群网站共用一份友链」这件事先跑起来。

    当然,这也带来边界:匿名发布要限制数量、限制请求大小、避免抓取内网地址、metadata 抓取要有超时。项目里现在对 URL 、私有地址、请求大小、最大站点数都做了一些限制。

    我不太想做成什么

    我不想把它做成站长版社交网络。

    也不想做成复杂的友情链接交易平台。

    更不想做成一个需要每天登录看的 dashboard 。

    我心里更接近的形态是:一份小小的公共名单,一段很轻的脚本,一种比较克制的互相推荐方式。它应该服务那些本来就互相认可的网站,而不是制造新的增长焦虑。

    可能的使用场景

    我目前想到的场景包括:

    • 几个朋友的博客互相推荐
    • 一个独立开发者的多个小产品互相导流
    • 一个 newsletter 作者群共享常读站点
    • 一个开源项目生态里推荐相关工具和教程
    • 一个小型内容社区维护成员站点目录

    比如一个产品作者有 5 个小工具站。如果每个站都手写一份「相关项目」,后面维护会很烦。用 LinkPals 就可以维护一份列表,每个站只展示与当前站最相关的几个。

    现在还在想的问题

    有些点我还没有完全想清楚,也想听听大家意见:

    1. 友链排序到底应该多自动,多少应该留给站长手动控制?
    2. 对中文个人站来说,大家更愿意用「自己托管 JSON 」还是「工具帮你发布一个稳定地址」?
    3. Widget 默认展示 4 个链接合不合理?还是 6 个更自然?
    4. 完整网络更适合做 drawer ,还是直接鼓励大家建 /friends 页面?
    5. 如果以后加审核/协作,应该保持 update key 这种轻权限,还是迟早需要账号?

    我个人目前的判断是:先把无账号、低维护、静态优先这条路走通,再考虑更重的功能。

    最后

    LinkPals 不是一个大项目,更像是我对「小网站之间能不能重新有一点连接感」的一个实验。

    现在很多流量入口都变得很集中,个人网站之间的横向发现反而弱了。友链这个东西看起来老,但它背后的需求其实还在:我喜欢你的站,所以愿意把你放在我的页面上;访问我的人,也可能会喜欢你。

    我想把这件事做得更轻、更好维护一点。

    如果你也有个人站、博客、独立项目,或者以前维护过友链,想听听你会不会用这样的东西,以及你觉得它最应该避免变成什么。

    4 replies    2026-05-28 16:28:46 +08:00
    geniushui
        1
    geniushui  
       1 day ago
    想法有点意思,推出来有点晚了。
    nicooolas
        2
    nicooolas  
    OP
       1 day ago
    @geniushui 兄弟,感谢认真读完了,我觉得这个点子还是蛮轻巧的,产品上也确实很方便,还是想多听听大家的一些建议,谢谢哈
    lolo1
        3
    lolo1  
       1 day ago via Android
    类似博客 10 年之约么
    nicooolas
        4
    nicooolas  
    OP
       1 day ago
    @lolo1 其实不只是博客,包括很多独立站,也可以用这个组件呀。一个开发者如果有好几个产品,而且在持续不断开发新产品的话,产品之间的互链维护还是很麻烦的,用这个组件就可以一套配置搞定了
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1698 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 51ms · UTC 16:18 · PVG 00:18 · LAX 09:18 · JFK 12:18
    ♥ Do have faith in what you're doing.