<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>T1ancheng的小窝</title>
  <link>https://t1anchengovo-blog.pages.dev</link>
  <description>高三在读生 爱玩CS2、Valorant、MC</description>
  <language>zh-CN</language>
  <lastBuildDate>Thu, 20 Aug 2026 16:14:52 GMT</lastBuildDate>
  <atom:link href="https://t1anchengovo-blog.pages.dev/feed.xml" rel="self" type="application/rss+xml"/>
<item>
  <title>用 Next.js 静态导出把博客部署到 Cloudflare Pages</title>
  <link>https://t1anchengovo-blog.pages.dev/posts/building-static-blog-on-cloudflare/</link>
  <guid isPermaLink="true">https://t1anchengovo-blog.pages.dev/posts/building-static-blog-on-cloudflare/</guid>
  <pubDate>Tue, 18 Aug 2026 00:00:00 GMT</pubDate>
  <description>从零搭一个 Markdown 驱动的静态博客：为什么选静态导出、关键的配置项，以及那些不踩不知道的坑。</description>
  <content:encoded><![CDATA[<p>这篇文章写的是这个博客自己是怎么被搭起来的。选择的过程、关键的配置，以及几个「不踩一遍就不知道」的坑。</p>
<h2>为什么是静态导出</h2>
<p>博客是典型的读多写少场景：文章是构建时确定的，不需要服务端按请求渲染。静态导出的好处很直接：</p>
<ul>
<li>没有服务端运行时，也就没有冷启动、没有计费单元，Cloudflare Pages 免费额度基本用不完。</li>
<li>每个页面就是一张 HTML，SEO 和首屏速度都占便宜。</li>
<li>部署形态极简：<code>next build</code> 产出一个 <code>out/</code> 目录，原样托管即可。</li>
</ul>
<p>代价同样明确——服务端能力一概没有。下面这张表把边界划清楚：</p>
<table>
<thead>
<tr>
<th>能力</th>
<th>静态导出下</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>动态路由</td>
<td>需要 <code>generateStaticParams</code></td>
<td>构建期枚举全部路径</td>
</tr>
<tr>
<td>API / Route Handlers</td>
<td>仅 GET + <code>force-static</code></td>
<td>可用来生成 feed.xml、sitemap</td>
</tr>
<tr>
<td>图片优化</td>
<td>默认不可用</td>
<td>用 <code>unoptimized</code> 或自定义 loader</td>
</tr>
<tr>
<td>ISR / Server Actions</td>
<td>不可用</td>
<td>构建期一次定型</td>
</tr>
</tbody>
</table>
<h2>三个关键配置</h2>
<p><code>next.config.ts</code> 只有几行，但每一行都有讲究：</p>
<figure data-rehype-pretty-code-figure=""><pre tabindex="0" data-language="ts" data-theme="github-light github-dark"><code data-language="ts" data-theme="github-light github-dark" style="display: grid;"><span data-line=""><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> type</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { NextConfig } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> "next"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span data-line=""> </span>
<span data-line=""><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> nextConfig</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> NextConfig</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span data-line=""><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  output: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"export"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span data-line=""><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  trailingSlash: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span data-line=""><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  images: { unoptimized: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span data-line=""><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">};</span></span>
<span data-line=""> </span>
<span data-line=""><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> nextConfig;</span></span></code></pre></figure>
<p><code>trailingSlash: true</code> 尤其重要。Cloudflare Pages 对目录有自己的一套规范化：<code>foo/index.html</code> 对应 <code>/foo/</code>。如果站内链接一会儿带斜杠一会儿不带，每个链接都会吃一次重定向，Search Console 里会冒出一堆「重定向」噪音。定死一个，全站一致。</p>
<h2>不写 not-found 会怎样</h2>
<p>这是最大的坑：<strong>Cloudflare Pages 检测不到顶层 <code>404.html</code> 时，会把站点当成 SPA</strong>，所有未匹配的路径都返回 200 和首页内容。</p>
<blockquote>
<p>死链返回 200，对 SEO 是灾难性的——搜索引擎会把根本不存在的页面当成真页面收录。</p>
</blockquote>
<p>Next.js 这边只要写一个 <code>app/not-found.tsx</code>，静态导出就会自动产出 <code>out/404.html</code>，问题解决。部署后记得验证：</p>
<figure data-rehype-pretty-code-figure=""><pre tabindex="0" data-language="bash" data-theme="github-light github-dark"><code data-language="bash" data-theme="github-light github-dark" style="display: grid;"><span data-line=""><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -o</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> /dev/null</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -w</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> "%{http_code}"</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> https://你的站.pages.dev/不存在的路径</span></span></code></pre></figure>
<p>预期返回 <code>404</code>，而不是 <code>200</code>。</p>
<h2>内容就是文件</h2>
<p>文章本身是仓库里的 Markdown，<code>frontmatter</code> 只用了四个字段：</p>
<figure data-rehype-pretty-code-figure=""><pre tabindex="0" data-language="yaml" data-theme="github-light github-dark"><code data-language="yaml" data-theme="github-light github-dark" style="display: grid;"><span data-line=""><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">---</span></span>
<span data-line=""><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">title</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"标题"</span></span>
<span data-line=""><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">date</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"2026-08-18"</span></span>
<span data-line=""><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">tags</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"标签"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]</span></span>
<span data-line=""><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">summary</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"一句话摘要"</span></span>
<span data-line=""><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">draft</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">false</span></span>
<span data-line=""><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">---</span></span></code></pre></figure>
<p><code>draft: true</code> 的文章会在构建期被整体剔除——不出现在首页、标签页、归档、RSS 和 sitemap 的任何一处。写一半的稿子可以放心地 push 上去。</p>
<h2>收尾</h2>
<p>到这里，一条「写完 → push → 自动部署」的闭环就通了。下面这张图是整体的数据流：</p>
<p><img src="/images/example-diagram.svg" alt="静态博客构建流程"></p>
<p>剩下的都是锦上添花：代码高亮、评论、RSS。它们会在后续迭代里一一补上。</p>]]></content:encoded>
</item>
<item>
  <title>为什么用 Markdown 写博客</title>
  <link>https://t1anchengovo-blog.pages.dev/posts/why-markdown/</link>
  <guid isPermaLink="true">https://t1anchengovo-blog.pages.dev/posts/why-markdown/</guid>
  <pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate>
  <description>写作工具越少越好：Markdown 让你把注意力放在字上，而不是放在排版按钮上。</description>
  <content:encoded><![CDATA[<p>选写作工具的标准只有一个：它能不能少打扰你。</p>
<p>Markdown 的正文就是纯文本，加粗、列表、引用都只是几个符号。写的时候没有格式工具栏在眼前晃，没有字号下拉框，没有「要不要加粗这段」的决策负担。注意力留在句子上，这比什么都值。</p>
<p>它的第二个好处是<strong>可移植</strong>。一份 <code>.md</code> 文件，今天在这个静态博客渲染，明天可以换个生成器，后天直接进 git 做版本管理。十年后大概率还能打开——纯文本不会过时。</p>
<p>代价是排版能力有限。但博客的长文，段落、标题、代码、引用、表格、图片，这些 Markdown 全都有。真要更复杂的版式，再写 HTML 也不迟。</p>
<p>少即是多，写作尤其如此。</p>]]></content:encoded>
</item>
</channel>
</rss>