独立开发者出海:从零上线一个证件照水印工具
从想法到上线,从 Web 到 Chrome 扩展,从免费到 Creem 支付接入——记录 ID Watermark 的完整开发历程和踩坑经验。
今年我开始做一个证件照水印工具,后来它变成了一个完整的出海产品。这篇文章记录整个过程。
为什么做这个工具?
想法很简单:国内办很多业务需要上传身份证、护照照片,但直接传原图不安全。加水印是刚需,但市面上没有好用的在线工具——要么要注册,要么会上传图片到服务器。
核心原则:所有处理在浏览器本地完成,不上传任何图片。
技术选型
| 技术 | 选择原因 |
|---|---|
| Next.js 15 | 熟悉,SSR 对 SEO 友好,静态导出成本低 |
| Canvas 2D | 纯前端图片处理,不需要后端 |
| Tailwind CSS | 够快,够轻 |
| WXT | Chrome 扩展框架,开发体验好 |
| Creem.io | 海外支付,支持 License Key 模式 |
Canvas 2D 水印引擎
核心是 Canvas 渲染。单点模式直接计算文字位置即可,平铺模式的关键是间距控制:
// 简化示意:遍历网格,在每个交点绘制水印文字
const step = fontSize + gap;
for (let r = -rows / 2; r < rows / 2; r++) {
for (let c = -cols / 2; c < cols / 2; c++) {
ctx.fillText(text, c * step, r * step);
}
}
实际实现还要处理旋转角度、透明度、对齐方式等,但核心逻辑就这么几行。
支付接入:Creem.io
海外支付是最头疼的一环。Stripe 门槛高,Paddle 审核慢。最后选了 Creem.io:
- License Key 模式,不需要自己管理用户系统
- API 简单,验证和激活只需要几个接口
- 5 美金/月,定价灵活

SEO:真正的坑
这是花时间最多的地方。独立站没人看,SEO 必须做好,但每一步都在踩坑:
坑 1:Sitemap 里写了错的 URL
因为用了 next-intl 的 localePrefix: 'as-needed',默认中文 locale 的 sitemap 写了 /zh,但 /zh 实际返回 307 跳转到 /。Google 跟着 sitemap 爬到一个跳转页,然后 canonical 又指回 /zh——陷入死循环。
修复:默认 locale 的 URL 不加前缀,/zh 改为 /。
坑 2:CSP 拦住了自己的 GA4
配了 Content Security Policy,但在控制台发现 GA4 数据一直为零。查了半天发现 connect-src 只写了 google-analytics.com,但 GA4 新版本用的是 analytics.google.com。
坑 3:子域名不被信任
主站 902077.xyz 和工具站 id-watermark.902077.xyz 是不同站点。Google 不会自动把主站的权重给子域名,必须在 Search Console 分别提交验证。
Chrome 扩展
Web 版做完后,我又用 WXT 做了 Chrome 扩展。技术实现上最有趣的部分是 Shadow DOM 样式隔离:
const shadow = container.attachShadow({ mode: 'open' });
const root = ReactDOM.createRoot(shadow);
root.render(<App />);
不这么做的话,扩展的样式会污染用户正在浏览的页面。
一些数据
- 一个 full-stack 开发者独立完成全部工作
- 从想法到上线 Web 版:约 3 周
- 再加 Chrome 扩展:1 周
- 基础设施成本很低(Vercel Hobby 额度足够)
总结
出海独立开发最大的挑战不是写代码,而是让产品被看到。SEO 配置、站点结构、外链建设——这些比功能本身花的时间还多。