<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: zongkai sun</title>
    <description>The latest articles on DEV Community by zongkai sun (@zongkai_sun_0946ae0d49db2).</description>
    <link>https://dev.to/zongkai_sun_0946ae0d49db2</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4099914%2Fb1fc9076-6450-4762-9ae3-b4a53c5a785c.png</url>
      <title>DEV Community: zongkai sun</title>
      <link>https://dev.to/zongkai_sun_0946ae0d49db2</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zongkai_sun_0946ae0d49db2"/>
    <language>en</language>
    <item>
      <title>5 Pilot Headshot Upgrades for a Better LinkedIn Profile</title>
      <dc:creator>zongkai sun</dc:creator>
      <pubDate>Tue, 22 Sep 2026 20:58:23 +0000</pubDate>
      <link>https://dev.to/zongkai_sun_0946ae0d49db2/5-pilot-headshot-upgrades-for-a-better-linkedin-profile-2fdo</link>
      <guid>https://dev.to/zongkai_sun_0946ae0d49db2/5-pilot-headshot-upgrades-for-a-better-linkedin-profile-2fdo</guid>
      <description>&lt;p&gt;Your LinkedIn photo is your first impression. For pilots, the right headshot communicates authority and approachability. Here are five concrete upgrades to make your profile land more opportunities.&lt;/p&gt;

&lt;p&gt;Read the full article on Portraze: &lt;a href="https://portraze.com/guides/5-pilot-headshot-upgrades-for-a-better-linkedin-profile" rel="noopener noreferrer"&gt;https://portraze.com/guides/5-pilot-headshot-upgrades-for-a-better-linkedin-profile&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>career</category>
      <category>design</category>
    </item>
    <item>
      <title>When Your Pet's Favorite Toy Becomes the Hardest Thing to Look At</title>
      <dc:creator>zongkai sun</dc:creator>
      <pubDate>Mon, 21 Sep 2026 17:08:21 +0000</pubDate>
      <link>https://dev.to/zongkai_sun_0946ae0d49db2/when-your-pets-favorite-toy-becomes-the-hardest-thing-to-look-at-164l</link>
      <guid>https://dev.to/zongkai_sun_0946ae0d49db2/when-your-pets-favorite-toy-becomes-the-hardest-thing-to-look-at-164l</guid>
      <description>&lt;p&gt;Discover how a beloved pet toy can become a grief trigger and learn gentle ways to transform it into a comforting memory keepsake during mourning.&lt;/p&gt;

&lt;p&gt;The moment you see the squeaky ball or tattered rope that your dog chased across the yard, your heart may tighten with an unexpected rush of sadness. That toy, once a source of pure joy, now sits as a silent reminder of the companion who is no longer there. Navigating that sharp sting is part of the mourning process, and finding ways to honor the toy can turn a painful trigger into a tender tribute.&lt;/p&gt;

&lt;p&gt;A pet toy is more than plastic or fabric; it is a sensory link to the routines you shared. The sound of a crinkling treat pouch, the worn spot where a cat pawed for hours, these details are encoded in your brain alongside the animal’s scent and movement. When the pet is gone, the toy suddenly carries the weight of that missing presence, and looking at it can summon the loss in an instant. This reaction is a natural part of grief, not a sign that you are overreacting.&lt;/p&gt;

&lt;p&gt;Every frayed edge or faded color tells a story. The squeaky mouse that sparked midnight playtime whispers that your cat once prowled the living room with midnight stealth. The rope that your rabbit shredded into a nest remembers the gentle nudges you gave each morning. Recognising these tiny narratives helps you see the toy as a record of love rather than just a painful symbol. By naming the moments attached to the object, you give yourself permission to feel the sadness without being overwhelmed by it.&lt;/p&gt;

&lt;p&gt;Instead of hiding the toy away, you can reshape its role in your grieving journey. Small, intentional actions let the object become a source of comfort rather than a trigger. Below are a few ideas you might try:&lt;/p&gt;

&lt;p&gt;It is okay to limit exposure to the toy until you feel steadier. Place it in a drawer, a high shelf, or a sealed bag, and note the date you tucked it away. Over time, you can revisit the item at your own pace, perhaps after a particularly tough day when you need a concrete anchor to the love you shared. Setting these boundaries respects both your emotional limits and the significance of the toy, allowing you to control when and how it re‑enters your daily life.&lt;/p&gt;

&lt;p&gt;Read the full article: &lt;a href="https://talepaws.com/blog/when-your-pet-s-favorite-toy-is-the-hardest-thing-to-look-at.html" rel="noopener noreferrer"&gt;TalePaws&lt;/a&gt;&lt;/p&gt;

</description>
      <category>pets</category>
      <category>mentalhealth</category>
      <category>life</category>
    </item>
    <item>
      <title>The Midnight Failure That Broke My Auto-Publishing Pipeline (and the Fix)</title>
      <dc:creator>zongkai sun</dc:creator>
      <pubDate>Fri, 18 Sep 2026 06:15:42 +0000</pubDate>
      <link>https://dev.to/zongkai_sun_0946ae0d49db2/the-midnight-failure-that-broke-my-auto-publishing-pipeline-and-the-fix-3g6n</link>
      <guid>https://dev.to/zongkai_sun_0946ae0d49db2/the-midnight-failure-that-broke-my-auto-publishing-pipeline-and-the-fix-3g6n</guid>
      <description>&lt;h1&gt;
  
  
  The Midnight Failure That Broke My Auto-Publishing Pipeline (and the Fix)
&lt;/h1&gt;

&lt;p&gt;I'm &lt;a href="https://xiaosuanshi.com" rel="noopener noreferrer"&gt;Xiaosuanshi&lt;/a&gt; (小算师) — a free site that serves daily horoscopes for all 12 Western zodiac signs &lt;em&gt;and&lt;/em&gt; 12 Chinese zodiac animals, fully automated. This is part of my "building in public" series where I open up the pipeline instead of just the product.&lt;/p&gt;

&lt;h2&gt;
  
  
  The incident
&lt;/h2&gt;

&lt;p&gt;One morning every social post failed at once. Tumblr, Bluesky, Mastodon, Blogger, dev.to, YouTube — all of them. The logs pointed at a missing manifest file. Digging further, the root cause was one silent line in the fallback path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// before — 兜底分支忘了落盘：&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;ANIMALS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// 页面有了，JSON 没写&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// after — 兜底也要写数据文件：&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fallbackAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dataFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// 下游永远有数据&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the AI engine hit its rate limit, the code fell back to template content. The &lt;strong&gt;HTML pages&lt;/strong&gt; still got generated — but the &lt;strong&gt;data JSON&lt;/strong&gt; never hit the disk. Everything downstream (pin generation → manifest → all 8 publishers) depends on that file, so the whole chain failed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 故障传播链（真实发生在一天凌晨）：&lt;/span&gt;
&lt;span class="c1"&gt;//   AI 限流 → 生肖数据 JSON 未落盘&lt;/span&gt;
&lt;span class="c1"&gt;//   → Pin manifest 生成失败&lt;/span&gt;
&lt;span class="c1"&gt;//   → 8 个发布平台全部依赖 manifest → 全军覆没&lt;/span&gt;
&lt;span class="c1"&gt;// 教训：数据生成与消费必须解耦；任何路径都要落盘，&lt;/span&gt;
&lt;span class="c1"&gt;//       不能只依赖"主路径成功"。&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What I changed
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Any path that produces content must persist it.&lt;/strong&gt; The fallback now writes the same data file the happy path writes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recovery, not just prevention.&lt;/strong&gt; I added a manual run mode so a single command regenerates the day's manifest (&lt;code&gt;node services/pinGenerator.js 2026-09-01&lt;/code&gt;) and republishes missed platforms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A one-line invariant:&lt;/strong&gt; publishers must throw a clear error naming the missing dependency, instead of a vague failure.
The fix has been live for a day and the pipeline recovered in ~15 minutes. If you automate publishing, audit your fallback paths — they are where silent bugs live.
## Today's reading
&lt;strong&gt;Year of the Goat — Friday, September 18, 2026&lt;/strong&gt; (Chinese zodiac animal)
Goats, today is a good day for personal growth. Invest in yourself.
&lt;strong&gt;Love&lt;/strong&gt;
Your partner will appreciate your efforts to improve yourself.
&lt;strong&gt;Career&lt;/strong&gt;
Focus on tasks that require patience and attention to detail.
&lt;strong&gt;Lucky number:&lt;/strong&gt; 2
&lt;strong&gt;Full reading:&lt;/strong&gt; &lt;a href="https://xiaosuanshi.com/chinese-zodiac-daily/goat/?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=daily-horoscope&amp;amp;utm_content=animal-goat" rel="noopener noreferrer"&gt;Xiaosuanshi&lt;/a&gt;
---
&lt;em&gt;One post a day from this project. All content is AI-generated for entertainment. Follow if you build in public too.&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>devops</category>
      <category>debugging</category>
    </item>
    <item>
      <title>Do you actually need eight glasses of water, for people who have tried everything, when the house is busy</title>
      <dc:creator>zongkai sun</dc:creator>
      <pubDate>Thu, 17 Sep 2026 02:12:47 +0000</pubDate>
      <link>https://dev.to/zongkai_sun_0946ae0d49db2/do-you-actually-need-eight-glasses-of-water-for-people-who-have-tried-everything-when-the-house-30hn</link>
      <guid>https://dev.to/zongkai_sun_0946ae0d49db2/do-you-actually-need-eight-glasses-of-water-for-people-who-have-tried-everything-when-the-house-30hn</guid>
      <description>&lt;p&gt;Eight glasses is a number with no particular evidence behind it. Thirst and urine colour are better guides.&lt;/p&gt;

&lt;p&gt;This is not complicated. It is inconvenient, which is why most people skip it.&lt;/p&gt;

&lt;p&gt;It works with other people in the house. You do not need silence.&lt;/p&gt;

&lt;p&gt;If you only do one thing from this page, do the first point below. It is first because it removes the most friction for the least effort.&lt;/p&gt;

&lt;p&gt;Food supplies a meaningful share of your water, especially fruit and vegetables.&lt;/p&gt;

&lt;p&gt;Your kidneys are extremely good at telling you what they need. Thirst is a reliable signal for healthy adults.&lt;/p&gt;

&lt;p&gt;Pale straw-coloured urine is the simplest check. Dark yellow means drink more; completely clear means you can stop.&lt;/p&gt;

&lt;p&gt;Tea and coffee count. The idea that they dehydrate you is largely wrong at normal intakes.&lt;/p&gt;

&lt;p&gt;There are real exceptions: hot weather, exercise, illness, pregnancy, and some medications. In those cases thirst lags behind need.&lt;/p&gt;

&lt;p&gt;Drinking more than you need does not improve skin, concentration or health. It mostly increases trips to the toilet.&lt;/p&gt;

&lt;p&gt;At normal intakes, no. The diuretic effect is small and does not outweigh the fluid you are taking in.&lt;/p&gt;

&lt;p&gt;Written for people who want the practical version. No accounts, no tracking, no newsletter wall.&lt;/p&gt;

&lt;p&gt;Read the full article: &lt;a href="https://softlystill.com/guides/do-you-actually-need-eight-glasses-of-water-for-people-who-have-tried-everything-when-the-house-is-busy" rel="noopener noreferrer"&gt;SoftlyStill: guided meditation&lt;/a&gt;&lt;/p&gt;

</description>
      <category>health</category>
      <category>mentalhealth</category>
      <category>life</category>
    </item>
    <item>
      <title>Dog ate rat poison — how long before symptoms appear?</title>
      <dc:creator>zongkai sun</dc:creator>
      <pubDate>Wed, 16 Sep 2026 07:58:24 +0000</pubDate>
      <link>https://dev.to/zongkai_sun_0946ae0d49db2/dog-ate-rat-poison-how-long-before-symptoms-appear-3o0m</link>
      <guid>https://dev.to/zongkai_sun_0946ae0d49db2/dog-ate-rat-poison-how-long-before-symptoms-appear-3o0m</guid>
      <description>&lt;p&gt;It depends on the poison type. Anticoagulant rat poisons cause bleeding that usually appears only 2–5 days later; cholecalciferol (vitamin D) poison causes kidney failure over days; bromethalin can cause seizures within…&lt;/p&gt;

&lt;p&gt;Read the full article: &lt;a href="https://askpettriage.com/en/dog-ate-rat-poison.html" rel="noopener noreferrer"&gt;askpettriage.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>A Grant-Winning Headshot: Show Your Artistic Credibility</title>
      <dc:creator>zongkai sun</dc:creator>
      <pubDate>Wed, 16 Sep 2026 07:58:21 +0000</pubDate>
      <link>https://dev.to/zongkai_sun_0946ae0d49db2/a-grant-winning-headshot-show-your-artistic-credibility-4kia</link>
      <guid>https://dev.to/zongkai_sun_0946ae0d49db2/a-grant-winning-headshot-show-your-artistic-credibility-4kia</guid>
      <description>&lt;p&gt;Your grant application headshot must balance professional trust with creative spirit. Here's how to use Portraze to craft an image that makes reviewers believe in your vision.&lt;/p&gt;

&lt;p&gt;Read the full article: &lt;a href="https://portraze.com/guides/a-grant-winning-headshot-show-your-artistic-credibility" rel="noopener noreferrer"&gt;Portraze&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Healing After Your Pet Was Killed by Another Dog</title>
      <dc:creator>zongkai sun</dc:creator>
      <pubDate>Wed, 16 Sep 2026 07:51:21 +0000</pubDate>
      <link>https://dev.to/zongkai_sun_0946ae0d49db2/healing-after-your-pet-was-killed-by-another-dog-2ko6</link>
      <guid>https://dev.to/zongkai_sun_0946ae0d49db2/healing-after-your-pet-was-killed-by-another-dog-2ko6</guid>
      <description>&lt;p&gt;Coping with the tragic loss of a pet due to a neighbor's dog attack. Find comfort, advice, and ways to honor your furry friend at TalePaws.com.&lt;/p&gt;

&lt;p&gt;Read the full article: &lt;a href="https://talepaws.com/blog/when-your-pet-was-killed-by-another-dog.html" rel="noopener noreferrer"&gt;TalePaws&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Rendering 24 Shareable Images a Day With HTML, CSS and Playwright</title>
      <dc:creator>zongkai sun</dc:creator>
      <pubDate>Wed, 16 Sep 2026 06:15:44 +0000</pubDate>
      <link>https://dev.to/zongkai_sun_0946ae0d49db2/rendering-24-shareable-images-a-day-with-html-css-and-playwright-5f2d</link>
      <guid>https://dev.to/zongkai_sun_0946ae0d49db2/rendering-24-shareable-images-a-day-with-html-css-and-playwright-5f2d</guid>
      <description>&lt;h1&gt;
  
  
  Rendering 24 Shareable Images a Day With HTML, CSS and Playwright
&lt;/h1&gt;

&lt;p&gt;I'm &lt;a href="https://xiaosuanshi.com" rel="noopener noreferrer"&gt;Xiaosuanshi&lt;/a&gt; (小算师) — a free site that serves daily horoscopes for all 12 Western zodiac signs &lt;em&gt;and&lt;/em&gt; 12 Chinese zodiac animals, fully automated. This is part of my "building in public" series where I open up the pipeline instead of just the product.&lt;/p&gt;

&lt;h2&gt;
  
  
  The render pipeline
&lt;/h2&gt;

&lt;p&gt;Every morning this site produces &lt;strong&gt;24 pin images&lt;/strong&gt; (12 zodiac signs + 12 Chinese zodiac animals) before any social post goes out. Instead of a canvas library or an image generator, each pin is just a static HTML template — 1000x1500, styled with CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* pinGenerator.js — 每张 Pin 就是一个 1000x1500 的 HTML 模板 */&lt;/span&gt;
&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;linear&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nf"&gt;gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;160&lt;/span&gt;&lt;span class="nx"&gt;deg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="nx"&gt;a0d0d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;d84343&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DejaVu Sans&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sans&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;flex&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;220&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;FFD166&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why HTML over canvas? Three practical reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fonts and emoji&lt;/strong&gt; render exactly like the real site (no bitmap font mismatch),&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gradients, shadows and Chinese glyphs&lt;/strong&gt; are handled by the browser engine for free,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every template is testable in a normal browser&lt;/strong&gt; before you screenshot it.
Then a headless Chromium takes a screenshot at 2x device scale, so the output is a crisp 2000x3000 raster:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 渲染交给 Playwright 无头 Chromium，一行截图&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;chromium&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;playwright&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;newPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;viewport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;deviceScaleFactor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;networkidle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;screenshot&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All 24 PNGs go into a folder with a &lt;code&gt;manifest.json&lt;/code&gt; that lists title, description, link and file for each pin. Publishing platforms only ever read that manifest — which is what makes the whole system composable: add a platform, and it just consumes the same manifest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Today's reading
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Year of the Horse — Wednesday, September 16, 2026&lt;/strong&gt; (Chinese zodiac animal)&lt;br&gt;
Horses, today is a day for adventure. Embrace new experiences.&lt;br&gt;
&lt;strong&gt;Love&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Your energy will be infectious in your relationship. Have fun together.&lt;br&gt;
&lt;strong&gt;Career&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Your adaptability will serve you well in your career. Be flexible.&lt;br&gt;
&lt;strong&gt;Lucky number:&lt;/strong&gt; 5&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Full reading:&lt;/strong&gt; &lt;a href="https://xiaosuanshi.com/chinese-zodiac-daily/horse/?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=daily-horoscope&amp;amp;utm_content=animal-horse" rel="noopener noreferrer"&gt;daily horoscope&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;One post a day from this project. All content is AI-generated for entertainment. Follow if you build in public too.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>playwright</category>
    </item>
    <item>
      <title>What to do when you wake at 3am — a calm, practical approach, when you are not in the mood</title>
      <dc:creator>zongkai sun</dc:creator>
      <pubDate>Wed, 16 Sep 2026 02:45:14 +0000</pubDate>
      <link>https://dev.to/zongkai_sun_0946ae0d49db2/what-to-do-when-you-wake-at-3am-a-calm-practical-approach-when-you-are-not-in-the-mood-2afp</link>
      <guid>https://dev.to/zongkai_sun_0946ae0d49db2/what-to-do-when-you-wake-at-3am-a-calm-practical-approach-when-you-are-not-in-the-mood-2afp</guid>
      <description>&lt;p&gt;Waking in the middle of the night is normal. What turns it into an hour of lying awake is the reaction to it.&lt;/p&gt;

&lt;p&gt;Read the full article on SoftlyStill: &lt;a href="https://softlystill.com/guides/what-to-do-when-you-wake-at-3am-a-calm-practical-approach-when-you-are-not-in-the-mood" rel="noopener noreferrer"&gt;sleep meditation&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>5 Smart LinkedIn Photo Upgrades for Dentists</title>
      <dc:creator>zongkai sun</dc:creator>
      <pubDate>Tue, 15 Sep 2026 20:55:13 +0000</pubDate>
      <link>https://dev.to/zongkai_sun_0946ae0d49db2/5-smart-linkedin-photo-upgrades-for-dentists-37ij</link>
      <guid>https://dev.to/zongkai_sun_0946ae0d49db2/5-smart-linkedin-photo-upgrades-for-dentists-37ij</guid>
      <description>&lt;p&gt;Your headshot is your first impression. We'll cover lighting, wardrobe, and expression to build trust before a patient even books. Avoid the common mistakes that make you look unapproachable.&lt;/p&gt;

&lt;p&gt;Read the full article on Portraze: &lt;a href="https://portraze.com/guides/5-smart-linkedin-photo-upgrades-for-dentists" rel="noopener noreferrer"&gt;AI headshot generator&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>When Your Pet Was the Last Tie to a Place You Left</title>
      <dc:creator>zongkai sun</dc:creator>
      <pubDate>Tue, 15 Sep 2026 17:45:13 +0000</pubDate>
      <link>https://dev.to/zongkai_sun_0946ae0d49db2/when-your-pet-was-the-last-tie-to-a-place-you-left-2c92</link>
      <guid>https://dev.to/zongkai_sun_0946ae0d49db2/when-your-pet-was-the-last-tie-to-a-place-you-left-2c92</guid>
      <description>&lt;p&gt;Explore how a pet can become the emotional bridge to an old home, offering comfort and practical ways to honor that pet memory of old home after moving away.&lt;/p&gt;

&lt;p&gt;Read the full article on TalePaws: &lt;a href="https://talepaws.com/blog/when-your-pet-was-the-last-tie-to-a-place-you-left.html" rel="noopener noreferrer"&gt;pet loss support&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>My Stack for a Fully Automated Content Site: AI + Static HTML + Staggered Pushes</title>
      <dc:creator>zongkai sun</dc:creator>
      <pubDate>Tue, 15 Sep 2026 06:55:43 +0000</pubDate>
      <link>https://dev.to/zongkai_sun_0946ae0d49db2/my-stack-for-a-fully-automated-content-site-ai-static-html-staggered-pushes-283n</link>
      <guid>https://dev.to/zongkai_sun_0946ae0d49db2/my-stack-for-a-fully-automated-content-site-ai-static-html-staggered-pushes-283n</guid>
      <description>&lt;h1&gt;
  
  
  My Stack for a Fully Automated Content Site: AI + Static HTML + Staggered Pushes
&lt;/h1&gt;

&lt;p&gt;I'm &lt;a href="https://xiaosuanshi.com" rel="noopener noreferrer"&gt;Xiaosuanshi&lt;/a&gt; (小算师) — a free site that serves daily horoscopes for all 12 Western zodiac signs &lt;em&gt;and&lt;/em&gt; 12 Chinese zodiac animals, fully automated. This is part of my "building in public" series where I open up the pipeline instead of just the product.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack in one line
&lt;/h2&gt;

&lt;p&gt;AI generates structured JSON → Node.js renders it to static HTML → a dynamic sitemap feeds search engines → a staggered scheduler pushes summaries to 7 platforms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Daily rhythm
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;00:00 UTC&lt;/strong&gt; — an AI engine writes fresh content for 12 signs + 12 animals (overview / love / career / luck).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;00:05&lt;/strong&gt; — 24 pin images render from HTML templates (see my post about the Playwright pipeline).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;01:00–12:00&lt;/strong&gt; — each platform posts on its own hour: Tumblr, Bluesky, Mastodon, Blogger, dev.to, YouTube Shorts, Telegraph.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;All day&lt;/strong&gt; — every page is pre-rendered static HTML, so there is no server-side render cost and nothing to cache.
The sitemap is assembled from module fragments so each new content type registers itself:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// server.js — sitemap 由各模块的片段动态合并&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/sitemap.xml&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;frags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="nf"&gt;coreRoutes&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nf"&gt;dailyFreshFragment&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nf"&gt;blogFragment&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;xml&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;assemble&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;frags&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What this buys a solo developer
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; the AI tier is free, the server is one 2-core VPS. Operating cost is basically zero.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SEO:&lt;/strong&gt; 300+ deep-linked static pages with JSON-LD, updated daily.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distribution:&lt;/strong&gt; 7 platforms, one pipeline, zero manual work.
The biggest lesson so far: automation is a system problem, not a script problem. The day one fallback path silently skipped a disk write and every publisher failed at once — since then, every path persists to disk before anything consumes it.
## Today's reading
&lt;strong&gt;Year of the Snake — Tuesday, September 15, 2026&lt;/strong&gt; (Chinese zodiac animal)
Today is a steady day for the Snake — your wise and mysterious nature helps you handle whatever comes your way.
&lt;strong&gt;Love&lt;/strong&gt;
In love, keep communication simple and honest. A small gesture of appreciation will be warmly received.
&lt;strong&gt;Career&lt;/strong&gt;
At work, focus on one priority at a time; your wise and mysterious qualities shine when you commit fully.
&lt;strong&gt;Lucky number:&lt;/strong&gt; 5
&lt;strong&gt;Full reading:&lt;/strong&gt; &lt;a href="https://xiaosuanshi.com/chinese-zodiac-daily/snake/?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=daily-horoscope&amp;amp;utm_content=animal-snake" rel="noopener noreferrer"&gt;free daily horoscope on Xiaosuanshi&lt;/a&gt;
---
&lt;em&gt;One post a day from this project. All content is AI-generated for entertainment. Follow if you build in public too.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>indie</category>
    </item>
  </channel>
</rss>
