<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Web on Yerong Li</title>
        <link>https://24ce4b33.yerong-li.pages.dev/tags/web/</link>
        <description>Curious about how the world works. Building, writing, learning.</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en</language>
        <managingEditor>ping@yerong.li (Yerong Li)</managingEditor>
        <webMaster>ping@yerong.li (Yerong Li)</webMaster>
        <copyright>© 2024-2026 · CC BY-NC 4.0</copyright>
        <lastBuildDate>Mon, 08 Jun 2026 14:22:32 +1000</lastBuildDate>
        <atom:link href="https://24ce4b33.yerong-li.pages.dev/tags/web/index.xml" rel="self" type="application/rss+xml" />
        <item>
            <title>Site Log 03: Shelf and Hoot</title>
            <link>https://24ce4b33.yerong-li.pages.dev/posts/2026/06/site-log-03-shelf-and-hoot/</link>
            <pubDate>Mon, 08 Jun 2026 14:22:32 +1000</pubDate>
            <author>ping@yerong.li (Yerong Li)</author>
            <guid>https://24ce4b33.yerong-li.pages.dev/posts/2026/06/site-log-03-shelf-and-hoot/</guid>
            <description>Explore Yerong Li&#39;s personal blog updates featuring the &#39;Shelf&#39; tool for Notion integration and &#39;Hoot&#39;, an AI assistant enhancing site interaction and contact methods.</description>
            <content type="html"><![CDATA[<h4 id="shelf">Shelf</h4>
<p>Shelf 这个功能复用了我之前的一个小项目。</p>
<p>我一直有在 Notion 里记录生活轨迹的习惯，主要是书和电影。早些时候，为了把 Notion 里的数据库改造得更好看，也更符合自己的使用习惯，我用 AI 帮忙写了一套网页信息抓取功能。后端主要由 Cloudflare Worker 处理抓取和写入。因为浏览器 extension 需要上架和审核，为了更轻量，前端触发方式最后做成了一个 bookmarklet。</p>
<p>再往后，我把授权部分拆成了 Notion OAuth。这样其他人如果复制了我的 Notion 模板，也可以一步步 set up，接入自己的 Notion workspace。这本来是一个独立的小工具。但在改进个人站时，我也想把这部分信息展示出来，而且最好能复用现有的东西。于是我在 Notion 数据库里多加了一个字段，用来选择某条记录是否 publish 到网站上，再通过 Worker 触发同步。</p>
<p>前端部分，尤其是效果和审美的实现，主要是靠 Claude 和 Gemini 一起讨论出来的。我发现 Codex 在这类视觉想象和风格探索上还欠缺许多，但它在把明确的方案落地成代码时很可靠。</p>
<p>6 月 7 号的这次更新，是在书籍和电影页面里加入了一个 Gesture Mode。此前我没有真正接触过视觉识别相关的东西，做这个的过程中才知道，浏览器里已经有很多成熟、免费的手部识别和 landmark detection 库可以使用，比如 MediaPipe Hands。这个功能本身只是一个小实验，但它让我很具体地意识到，在很近的未来，人与电子信息的日常交互未必还要被鼠标和键盘这套模式牢牢限制住。</p>
<h4 id="hoot-">Hoot 🦉</h4>
<p>Hoot 的产生，最开始是因为我想在这个个人站里更显性地引入 AI。尽管在写作流程里，其实已经有 AI 生成 metadata 的环节，但那更像是后台流程的一部分，并不是访客可以直接感知到的东西。</p>
<p>创造大概有两种方式。一种是先有问题，然后寻找解决问题的工具。这个工具可以是现有的，也可以是从无到有生出来的。另一种方式是先有工具，然后再考虑它可以解决什么问题。后一种方式里的问题通常没有那么迫切，否则大概早就会采取第一种方式了。</p>
<p>在这里，我是先有了 AI 这个工具，才很自然地开始想：它能做什么？大语言模型的特性是能“说人话”，而现在的检索、索引和工具调用能力，又让它有机会说一些有依据的人话。于是便有了 Hoot：一个可以回答我公开信息的 assistant。</p>
<p>AI 还有调用工具的能力，所以它也很自然地改进了 contact 功能。以前传统博客通常是在 Contact 页面放一个 email 地址，或者触发邮件客户端。而 Hoot 可以在相关对话里触发 workflow，把信息发送到我的 Telegram bot。额外的，我也可以知道联系者在发起联系前问过哪些问题，从而理解这个联系发生的上下文。</p>
<h2 id="english-version">English version</h2>
<h4 id="shelf-1">Shelf</h4>
<p>The Shelf feature reuses a small project I had built earlier.</p>
<p>I have long had the habit of recording traces of my life in Notion, mostly books and films. Earlier, in order to make my Notion database look better and fit my own usage habits more closely, I asked AI to help me build a web information scraping workflow. The backend is mainly handled by Cloudflare Workers, which fetch information and write it into Notion. Because publishing and reviewing a browser extension would add extra friction, I made the front-end trigger a lightweight bookmarklet instead.</p>
<p>Later, I separated the authorization flow into Notion OAuth. This means that if someone copies my Notion template, they can set it up step by step and connect it to their own Notion workspace. Originally, this was an independent tool. But while improving my personal site, I also wanted to show part of this information here, ideally by reusing what already existed. So I added another field in the Notion database to decide whether a record should be published to the website, then used a Worker to trigger the sync.</p>
<p>The front-end part, especially the interaction and visual direction, came mostly from discussions with Claude and Gemini. I find that Codex is still weaker at this kind of visual imagination and style exploration, but it is reliable when the plan is already clear and needs to be turned into code.</p>
<p>The June 7 update added Gesture Mode to the books and films pages. Before this, I had not really worked with computer vision. During the process, I learned that there are already mature and free hand-tracking and landmark detection libraries available in the browser, such as MediaPipe Hands. The feature itself is only a small experiment, but it made me feel very concretely that in the near future, everyday interaction with digital information may not need to remain so tightly bound to the familiar mouse-and-keyboard model.</p>
<h4 id="hoot--1">Hoot 🦉</h4>
<p>Hoot began with a simple desire: I wanted to introduce AI into this personal site in a more visible way. AI was already part of my writing workflow, especially in generating metadata, but that was more of a background process. It was not something visitors could directly experience.</p>
<p>There are roughly two ways to create things. One starts with a problem, then looks for a tool to solve it. The tool can already exist, or it can be built from scratch. The other starts with a tool, then asks what problems it might solve. Problems in the second category are usually less urgent; otherwise, they would probably have already triggered the first path.</p>
<p>Here, I had AI as a tool first, and it was natural to start asking: what can it do? The defining quality of large language models is that they can speak in human language. With today&rsquo;s retrieval, indexing, and tool-calling capabilities, they can also speak with some grounding. That became Hoot: an assistant that can answer questions about my public information.</p>
<p>AI can also call tools, so it naturally improved the contact flow as well. A traditional blog usually puts an email address on the Contact page, or opens an email client. Hoot can trigger a workflow during a relevant conversation and send the message to my Telegram bot. As an extra benefit, I can also see what questions the person asked before contacting me, which gives me more context for why the contact happened.</p>
]]></content>
        </item>
        <item>
            <title>Site Log 01: Small Desires</title>
            <link>https://24ce4b33.yerong-li.pages.dev/posts/2026/06/site-log-01-small-desires/</link>
            <pubDate>Mon, 08 Jun 2026 12:52:36 +1000</pubDate>
            <author>ping@yerong.li (Yerong Li)</author>
            <guid>https://24ce4b33.yerong-li.pages.dev/posts/2026/06/site-log-01-small-desires/</guid>
            <description>Explore how AI tools like Codex and Cloudflare Workers can transform a static blog into a dynamic, functional, and beautiful personal space with unique features.</description>
            <content type="html"><![CDATA[<p>近来有点沉迷于用 Codex 实现各种突然冒出来的想法。</p>
<p>这个网站之前只是一个简单的 Hugo 静态博客，托管在 GitHub 上。那时还没有 AI 帮忙，只能尽量找别人搭好的 UI 框架，可以改动的地方少得可怜。后来冒出一个念头：让 Codex 帮我把网站大改一遍。于是我把网站迁移到了 Cloudflare。除了前端样式终于可以相对“随心所欲”地调整，也顺手加了几个额外的小功能。</p>
<p>时间过去并不久，但我已经有点记不清最初为什么想做这些东西了。若要细究，可能是因为之前做别的项目时发现 Cloudflare 有很多免费、好用、并且对个人项目非常友好的东西。比如 Cloudflare Workers，它是运行在 Cloudflare 边缘网络上的 serverless 运行时，概念上有点像 AWS Lambda@Edge：不需要自己维护服务器，却可以在离用户更近的地方处理请求。知道了有什么工具，剩下的就变成了关于小小欲望的问题：我到底想要什么？</p>
<p>我希望这里不只是一个能放文字的地方。它应该有真正的功能性，也应该是美的。除此之外，这里除了是我的个人空间，也可以是一个建立 connection 的场所。于是有了下面两个小部分，可以在桌面端首页看到：</p>
<h4 id="thoughts">Thoughts</h4>
<p>最开始的念头是，我想要一个能“发推特”的地方。Blog 偏向于长文，并不是一个能常常更新的地方。更多时候，我的表达欲望只是一句话，需要一个即时的出口。于是产生了这个 Thoughts 块：它连接了我的 Telegram bot，后端由 Cloudflare Workers 实现。</p>
<h4 id="visitors">Visitors</h4>
<p>这里除了是我的空间，也希望能留下别人的痕迹。后续我可能会进一步加上评论功能，但在那之前，我想先有一个更轻、更好玩的“留爪”功能。</p>
<p>兼顾成本和趣味之后，就有了 Visitors 块。它在首页右侧，访客可以留下姓名和坐标。由于 vibe coding 很多时候只需要告诉 AI 我想要什么，具体技术细节不一定要马上知道，所以很长一段时间里，我其实并不知道这些访客信息到底存到了哪里。直到后来让朋友帮忙测试时，触发了操作过多的 limit，我才开始关注这个问题，问 Codex 它到底把数据存在哪里、limit 又是怎么实现的。由此才知道，它当时使用了 Cloudflare Cache 来保存和读取这类轻量状态，并用缓存键与过期时间做了简单的限流。</p>
<p>严格说，Cloudflare Cache 更适合缓存请求响应，并不是一个真正的数据库。如果这个功能之后变得更正式，应该迁移到 Cloudflare KV、D1 或 Durable Objects 这类更明确的存储方案。但对这个轻量、低成本、带实验性质的小模块来说，Cache 的确暂时够用。</p>
<p>另外值得一提的是，最初这个模块并没有这么好玩，只有文字信息，显得有点干巴巴的。好像是朋友的一句话，说文字漂浮的效果像“小魂儿”，于是才有了后来这个更具象的小魂儿。</p>
<p>现在和 Codex 合作做东西时，我最喜欢的部分常常是：如果暂时不考虑技术限制，我能想象出什么？这个过程中，想象力很多时候是模糊的，需要和 ChatGPT、Claude 讨论很多次。一个很惊喜的点是，Claude 在和我确认具体想象时，会主动直接帮我画出来，包括配色方案，也包括这个小魂儿的效果。然后我拿着它生成的 prompt，再继续让 Codex 真的把它实现出来。</p>
<h2 id="english-version">English version</h2>
<p>Recently, I have been slightly obsessed with using Codex to build all kinds of ideas that suddenly come to mind.</p>
<p>This website used to be a simple Hugo static blog hosted on GitHub. Back then, without AI helping me, I could only rely on UI frameworks built by others, which left very little room for meaningful customization. Later, I had the idea of asking Codex to help me redesign the site, and I migrated it to Cloudflare. Besides making the front-end style much easier to adjust, I also added a few small features.</p>
<p>Not much time has passed, but I already find it a little hard to remember why I decided to build these things in the first place. If I trace it back, it probably started from other projects where I discovered that Cloudflare offers many free, powerful, and personal-project-friendly tools. Cloudflare Workers, for example, is a serverless runtime running on Cloudflare&rsquo;s edge network. Conceptually, it is somewhat similar to AWS Lambda@Edge: I do not need to maintain my own server, but I can still process requests closer to users. Once I knew what tools were available, the rest became a question of small desires: what exactly did I want?</p>
<p>I wanted this site to be more than a place for text. It should be functional, and it should also be beautiful. Beyond that, while this is my personal space, it can also be a place for connection. That led to the following two small sections, which can be seen on the desktop homepage:</p>
<h4 id="thoughts-1">Thoughts</h4>
<p>The original idea was simple: I wanted a place where I could &ldquo;tweet.&rdquo; A blog is more suited to long-form writing, and it is not something I update constantly. Most of the time, my urge to express something is only a sentence long. It needs an immediate outlet. That is how the Thoughts section came about: it is connected to my Telegram bot, with the backend implemented through Cloudflare Workers.</p>
<h4 id="visitors-1">Visitors</h4>
<p>Besides being my own space, I also wanted this site to leave traces of other people. I may add a proper comment feature later, but before that, I wanted something lighter and more playful.</p>
<p>Balancing cost and fun led to the Visitors section. It sits on the right side of the homepage, where visitors can leave their name and location. Since vibe coding often lets me simply tell AI what I want without immediately understanding every technical detail, for quite a while I actually did not know where these visitor records were stored. It was only after I asked friends to test the feature and they triggered a rate limit that I started paying attention. I asked Codex where the data was stored and how the limit was implemented. That was when I learned that it was using Cloudflare Cache to store and retrieve this lightweight state, with cache keys and expiration times providing a simple form of rate limiting.</p>
<p>Strictly speaking, Cloudflare Cache is better suited for caching request responses; it is not a real database. If this feature becomes more formal later, it should probably move to Cloudflare KV, D1, or Durable Objects, which are clearer storage options. But for a lightweight, low-cost, experimental feature like this, Cache is good enough for now.</p>
<p>Another detail worth mentioning is that this module was not very fun at first. It only showed text, which felt dry. Then a friend said the floating text looked like little wandering spirits, and that comment eventually became the more concrete little spirit you see now.</p>
<p>One of my favorite parts of working with Codex is asking myself: if I temporarily ignore technical constraints, what can I imagine? During this process, imagination is often blurry, and I need to discuss the idea with ChatGPT and Claude many times. One surprising thing is that Claude sometimes helps me make the idea visual while confirming it with me, including color palettes and the effect of the little spirit. Then I take the prompt it generates and ask Codex to actually implement it.</p>
]]></content>
        </item>
        
    </channel>
</rss>

