实战:为 Hugo 博客开发一个公网 IP 探测 Shortcode

工具说明:在进行内网穿透(如调试 mole-go)或配置服务器白名单时,频繁查询公网 IP 是刚需。为了告别繁琐的登录和搜索,我开发了这个集成在博客中的实时探测组件。 🌐 公网 IP 探测 🌐 当前公网 IP: 正在探测... 复制 🛠️ 核心实现逻辑 这个工具基于 Hugo 的 Shortcode 功能实现,采用了异步加载技术,确保不会影响页面的首屏渲染速度。 ...

2026-02-03 · 2 min · Eagle

从 mdBook 到 Hugo:一位后端开发者的博客架构演进与思考

在数字内容创作的旅程中,工具的选择往往折射出创作者在不同阶段的诉求。从最初的小程序“豆子碎片”,到尝试使用 Rust 生态的 mdBook,再到最终回归并定于 Hugo,这不仅是技术栈的迁移,更是我对内容分发、用户体验以及商业化潜力深度思考后的结果。 1. 痛定思痛:告别移动端封闭生态的束缚 最初,我将大量的笔记和技术心得打造成了一个名为“豆子碎片”的小程序。初衷是利用移动端的便捷性,但随着内容的积累,弊端逐渐显现。 最直观的痛点在于性能与体验。小程序在渲染长篇幅的技术文章,尤其是包含大量代码片段的内容时,卡顿感非常明显。更重要的是,作为一名开发者,我发现小程序在内容搜索与社交分享上存在天然的屏障。技术内容应当是开放的,它需要被搜索引擎检索,也需要方便地在网页端被阅读和引用。 为了打破这种孤岛状态,我决定回归网站博客。 2. 抉择:为什么不是 mdBook? 在回归 Web 的第一站,我首先关注到了 mdBook。作为一个偏爱简洁风格的开发者,mdBook 这种类似文档流的展示方式起初非常吸引我。然而,在深入使用并尝试进行定制化开发时,我遇到了一些瓶颈。 扩展性的局限 mdBook 虽然在文档编写上非常纯粹,但在作为通用博客平台的扩展性上显得略为乏力。由于它主要为 Rust 文档设计,当我试图通过编写插件来处理一些特殊逻辑时(例如将我在小程序中定义的私有格式 type|url|params 自动还原为标准 URL 链接),开发过程并不如预期般顺遂。 技术栈的契合度 作为一名后端开发者,我对 Go 语言 拥有更高的熟悉度。在折腾 mdBook 插件遇到阻碍后,我意识到:用熟不用生不仅是开发经验,更是提升生产力的核心。 3. 回归 Hugo:灵活性与商业化的平衡 最终选择 Hugo,是我在权衡了扩展性、性能与长期维护成本后的决定。 强大的扩展能力与 Go 生态 Hugo 作为基于 Go 语言构建的静态网站生成器,其渲染速度堪称业界天花板。更重要的是,它的模板系统极其灵活。对于我之前在小程序中定义的自定义链接格式,我可以通过 Hugo 的 Shortcodes 或正则表达式替换轻松实现自动化转换。这种“随心所欲”的控制感,是后端开发者最看重的。 布局与精力的分配 在经历了几年的技术折腾后,我悟出了一个道理:开发者的时间应该花在内容创作上,而不是无休止地调整 CSS 布局。 我选择了 PaperMod 主题,因为它精准地命中了我所有的痛点: 极致简洁:没有冗余的装饰,让读者聚焦于文字。 响应式设计:完美适配手机端阅读,填补了告别小程序后的移动端体验。 易于 SEO:内置了完善的 SEO 结构,为后续的流量增长打下基础。 4. 商业化的考量:为了 Google AdSense 之所以选择 Hugo 而非继续留在 mdBook,还有一个非常现实的原因——流量主申请与广告布局。 ...

2026-02-10 · 1 min · Eagle

Hugo 进阶:集成 Google Analytics 4 与站点收录优化

完成网站搭建后,下一步便是集成 Google Analytics (GA4) 以及优化搜索引擎收录。对于我来说,这不仅仅是技术配置,更是将以前域名的冗余资源清理掉,赋予这个站点一个干净、纯粹的起点。 1. 集成 Google Analytics 统计分析 在 FixIt 主题中,集成统计分析需要配置 Hugo 的内置服务与主题插件。 在 hugo.toml 文件中进行如下配置: # 1. 开启 Hugo 内置的 Google Analytics 服务 [services] [services.googleAnalytics] ID = 'G-XXXXXXXXXX' # 替换为您在 GA4 获取的“衡量 ID” # 2. 配置 FixIt 主题的分析插件 [params] [params.analytics] enable = true type = "google" # 指定类型为 google [params.analytics.google] id = "G-XXXXXXXXXX" async = true # 开启异步加载,避免统计代码影响网页首屏加载速度 站长提示:配置完成后,建议在本地运行 hugo server 并使用 F12 检查网络请求,确认是否有来自 google-analytics.com 的数据上报。 2. 提交 Sitemap 与清理旧资源 为了让 Google 更好地爬取新内容,并彻底告别过去,我们需要通过 Google Search Console 进行以下操作。 ...

2026-01-02 · 1 min · Eagle

Hugo 进阶:FixIt 主题深度配置(目录结构、多级菜单与 Logo)

在完成第一篇文章的发布后,趁热打铁记录下 FixIt 主题的深度定制备忘,重点解决内容组织架构与导航体验。 1. 内容目录架构:从逻辑到物理组织 为了方便管理 9 年来的技术沉淀,我决定不依赖 Hugo 的扁平化展示,而是通过文件夹在物理层面进行分类,将其划分为 “项目实战” 与 “技术随笔” 两大板块。 项目实战 (Projects) 在 content/projects/ 目录下,采用“一项目一文件夹”的结构。每个文件夹内放置 _index.md 标识该板块为一个 Section。 路径示例:content/projects/mole-client/_index.md 配置内容: +++ title = "Mole 客户端 (frp管理)" layout = "section" draft = false +++ 注意:在父级 projects/ 下也要放置一个 _index.md 作为项目总列表。 技术随笔 (Posts) 日常记录存放于 content/posts/。不需要 _index.md,直接通过文章开头的 Front Matter 进行分类。 示例 Front Matter: categories: ["deploy"] # 将分类设为 deploy,Hugo 会自动将其归档至对应分类页 2. 导航菜单配置:构建多级下拉菜单 在 hugo.toml 中,通过 identifier 和 parent 的配合,我为“技术笔记”板块设计了下拉菜单,使导航更具条理性。 [menu] # 首页入口 [[menu.main]] identifier = "home" name = "首页" url = "/" pre = '<i class="fa-solid fa-home fa-fw"></i>' weight = 1 # --- 技术笔记下拉菜单 --- # 1. 父级入口:点击不跳转,仅用于展开子项 [[menu.main]] identifier = "notes" name = "技术笔记" url = "#" pre = '<i class="fa-solid fa-book fa-fw"></i>' weight = 2 # 2. 子菜单:小程序 [[menu.main]] parent = "notes" identifier = "mp" name = "小程序" url = "/categories/mp/" pre = '<i class="fa-solid fa-mobile-screen-button fa-fw"></i>' weight = 1 # 3. 子菜单:Go 语言 [[menu.main]] parent = "notes" identifier = "go" name = "Go 语言" url = "/categories/go/" pre = '<i class="fa-brands fa-golang fa-fw"></i>' weight = 2 # 4. 子菜单:Rust 语言 [[menu.main]] parent = "notes" identifier = "rust" name = "Rust 语言" url = "/categories/rust/" pre = '<i class="fa-brands fa-rust fa-fw"></i>' weight = 3 # 5. 子菜单:部署运维 [[menu.main]] parent = "notes" identifier = "deploy" name = "部署实战" url = "/categories/deploy/" pre = '<i class="fa-solid fa-cloud-arrow-up fa-fw"></i>' weight = 4 # --- 其他一级菜单 --- [[menu.main]] identifier = "projects" name = "项目实战" url = "/projects/" pre = '<i class="fa-solid fa-layer-group fa-fw"></i>' weight = 10 [[menu.main]] identifier = "about" name = "关于我" url = "/about/" pre = '<i class="fa-solid fa-user-circle fa-fw"></i>' weight = 20 3. 视觉识别:更换站点 Logo 作为“ 豆子技术站”的标志,我选择了 Ostrich 图标。 ...

2026-01-01 · 2 min · Eagle

从零到一:Hugo 项目部署 Cloudflare Pages 避坑指南

今天“ 豆子技术站”正式上线了!虽然部署过程只用了几个小时,但中间踩了不少坑。为了让大家少走弯路,我把这段折腾经历记录下来。 为什么选择 Hugo + GitHub + Cloudflare? 我有自己的服务器,最初想用 mdBook。但 mdBook 适合书籍展示,格式太固定,不适合折腾。最终我选择了 Hugo —— 虽有一段时间没用,但基础还在。 在主题选型上我花了不少时间,从花哨的 Blowfish 转向了更严谨的 FixIt。虽然我的重心正转向 Go 和 Rust,但 2026 年初的首要任务是搭建好这个支持中英双语的“根据地”。 站长忠告:切忌心急。 很多弯路其实是因为没读懂 Cloudflare 的英文提示就直接上手导致的。 避坑指南:我踩过的六个坑 1. 误判服务:Workers 还是 Pages? 这是最尴尬的一个坑。我一直在 Cloudflare Workers 里折腾,结果页面永远显示 Hello World。AI 告诉我是配置文件没生效,我折腾半天无果,最后通过 Google 搜索才发现:我要部署的是静态站(Pages),而不是函数脚本(Workers)。换成 Pages 服务后,一遍过。 2. DNS 托管的“心理障碍” Cloudflare 的免费计划要求将 DNS 托管给它。起初我很抗拒,因为我还有阿里云的子域名(如小程序后端 mp)在运行,担心影响原有业务。 解决方法:在域名注册商后台将 DNS 服务器换成 Cloudflare 提供的地址。 关键点:激活后,记得把原来的解析记录在 Cloudflare 重新添加一遍。以后新增解析都在 Cloudflare 完成。 3. 页面样式“裸奔”:baseURL 没填对 部署完成后,网站能打开但没有样式(CSS 加载失败)。 原因:F12 检查发现 URL 地址不对。 解决:在 hugo.toml 中将 baseURL 修改为你的自定义域名。 进阶:在 Cloudflare 构建命令中使用 hugo -b $CF_PAGES_URL,系统会自动处理域名。 4. CNAME 无法直接生效 我起初打算在原域名商处使用 CNAME,但死活打不开。事实证明,为了享受 Cloudflare 的全套防护和证书服务,DNS 托管是最高效的选择。 ...

2026-01-01 · 1 min · Eagle