大家好,我最近在做一个小产品,叫 LinkPals。它想解决的不是一个很宏大的问题,而是一个在独立站、博客、个人项目里很常见但一直有点尴尬的小问题:友链怎么做,才既真的有用,又不把每个网站的 footer 变成一堵链接墙。
一句话介绍:LinkPals 是一个给小型网站圈子用的友链组件。几个网站共用一份 friends.json,每个站点只嵌入一段 JS ,页面上默认只展示 4 到 8 个精选链接,完整网络则放在抽屉或 /friends 页面里。
我先把 demo 和代码结构做出来了,目前还是早期版本,所以更想听听大家对这个方向的判断。
[推广] Krill 福利加倍送,持续送,回贴就送,反正就是送~纯 pro 号池低至 0.13, image-2 免费用 , dp-v4-flash 官方 4 折!
[AI Agent 智能体] 越来越怀疑,很多 Agent 现在根本进不了企业
为什么想做这个
友链其实是老互联网里一个很有温度的东西。
以前逛博客,经常会从一个作者的链接页跳到另一个站,慢慢摸到一小片人的网络。相比搜索引擎和信息流,这种发现方式很慢,但也很有上下文:你知道这个链接不是算法随机推给你的,而是某个站长真的愿意放在自己页面上的。
但现在再给网站加友链,会遇到几个现实问题:
- 如果每个站都放完整列表,footer 很快会失控。
- 如果只放几个链接,又很难保持公平,后续也不好维护。
- 如果每个站单独维护一份 HTML ,更新一次要改很多地方。
- 如果做成 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 就可以维护一份列表,每个站只展示与当前站最相关的几个。
现在还在想的问题
有些点我还没有完全想清楚,也想听听大家意见:
- 友链排序到底应该多自动,多少应该留给站长手动控制?
- 对中文个人站来说,大家更愿意用「自己托管 JSON 」还是「工具帮你发布一个稳定地址」?
- Widget 默认展示 4 个链接合不合理?还是 6 个更自然?
- 完整网络更适合做 drawer ,还是直接鼓励大家建
/friends页面? - 如果以后加审核/协作,应该保持 update key 这种轻权限,还是迟早需要账号?
我个人目前的判断是:先把无账号、低维护、静态优先这条路走通,再考虑更重的功能。
最后
LinkPals 不是一个大项目,更像是我对「小网站之间能不能重新有一点连接感」的一个实验。
现在很多流量入口都变得很集中,个人网站之间的横向发现反而弱了。友链这个东西看起来老,但它背后的需求其实还在:我喜欢你的站,所以愿意把你放在我的页面上;访问我的人,也可能会喜欢你。
我想把这件事做得更轻、更好维护一点。
如果你也有个人站、博客、独立项目,或者以前维护过友链,想听听你会不会用这样的东西,以及你觉得它最应该避免变成什么。