<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Static Sites on KnightLi Blog</title>
        <link>https://www.knightli.com/en/tags/static-sites/</link>
        <description>Recent content in Static Sites on KnightLi Blog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en</language>
        <lastBuildDate>Sun, 17 May 2026 20:00:17 +0800</lastBuildDate><atom:link href="https://www.knightli.com/en/tags/static-sites/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>How to Use Hugo aliases: Old URL Redirects and 404 Fix Guide</title>
        <link>https://www.knightli.com/en/2026/05/17/hugo-aliases-url-redirect/</link>
        <pubDate>Sun, 17 May 2026 20:00:17 +0800</pubDate>
        
        <guid>https://www.knightli.com/en/2026/05/17/hugo-aliases-url-redirect/</guid>
        <description>&lt;p&gt;Hugo &lt;code&gt;aliases&lt;/code&gt; create redirects for old page URLs.&lt;/p&gt;
&lt;p&gt;When you change an article URL, merge pages, migrate a blog, or want to fix a common mistaken URL, you can add &lt;code&gt;aliases&lt;/code&gt; in the article&amp;rsquo;s Front Matter. Hugo generates redirect pages for those old addresses and sends visitors to the current page, avoiding unnecessary 404 errors.&lt;/p&gt;
&lt;h2 id=&#34;what-aliases-are-useful-for&#34;&gt;What aliases are useful for
&lt;/h2&gt;&lt;p&gt;There are three common scenarios.&lt;/p&gt;
&lt;p&gt;The first is improving article URLs.&lt;/p&gt;
&lt;p&gt;For example, your old article URL might be:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/posts/tech/2023-01-01-hello/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Later you may want to shorten it to:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/hello/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;In that case, add the old URL as an alias on the new page. Search engines, external references, and social links can still reach the content.&lt;/p&gt;
&lt;p&gt;The second scenario is merging or migrating pages.&lt;/p&gt;
&lt;p&gt;If you merge several old posts into a new one, or migrate from Hexo, Typecho, WordPress, or another platform to Hugo, the old URL structure often differs from the new site. &lt;code&gt;aliases&lt;/code&gt; can point those old addresses to the new pages one by one and reduce post-migration 404s.&lt;/p&gt;
&lt;p&gt;The third scenario is fixing spelling mistakes.&lt;/p&gt;
&lt;p&gt;Some URLs may have been written incorrectly, or external sites may already link to the wrong path. If that wrong link receives traffic, you can create a dedicated alias for it and still guide users to the correct page.&lt;/p&gt;
&lt;h2 id=&#34;basic-syntax&#34;&gt;Basic syntax
&lt;/h2&gt;&lt;p&gt;Add an &lt;code&gt;aliases&lt;/code&gt; field in the article Front Matter.&lt;/p&gt;
&lt;p&gt;YAML example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;New Article Title&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;ld&#34;&gt;2026-05-17T12:00:00&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;+09&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/new-path/my-new-article/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;aliases&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;/old-path/old-article/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;../old-version/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Here &lt;code&gt;/old-path/old-article/&lt;/code&gt; is a site-relative path. &lt;code&gt;../old-version/&lt;/code&gt; is relative to the current page.&lt;/p&gt;
&lt;p&gt;In practice, site-relative paths that start with &lt;code&gt;/&lt;/code&gt; are usually easier to reason about. They are clearer and less likely to break when the article directory structure changes.&lt;/p&gt;
&lt;h2 id=&#34;relationship-with-the-url-field&#34;&gt;Relationship with the url field
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;url&lt;/code&gt; defines the new address of the current page.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;aliases&lt;/code&gt; defines which old addresses redirect to that new address.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/new-path/my-new-article/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;aliases&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;/old-path/old-article/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;After the site is built, visitors to &lt;code&gt;/old-path/old-article/&lt;/code&gt; will be redirected to &lt;code&gt;/new-path/my-new-article/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If the article does not explicitly set &lt;code&gt;url&lt;/code&gt;, Hugo generates the current page URL from the site&amp;rsquo;s &lt;code&gt;permalinks&lt;/code&gt; configuration, the article date, slug, and other rules. &lt;code&gt;aliases&lt;/code&gt; will still point to that final generated page.&lt;/p&gt;
&lt;h2 id=&#34;how-hugo-implements-redirects-by-default&#34;&gt;How Hugo implements redirects by default
&lt;/h2&gt;&lt;p&gt;By default, Hugo generates a separate HTML file for each alias.&lt;/p&gt;
&lt;p&gt;That HTML file usually uses:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;meta&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;http-equiv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;refresh&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This makes the browser automatically redirect from the old address to the new one.&lt;/p&gt;
&lt;p&gt;This approach is simple, portable, and works well on ordinary static hosting. But it is a browser-side redirect, not a server-side 301 or 302 redirect.&lt;/p&gt;
&lt;p&gt;For small sites, this is often enough. As long as the old address opens and eventually reaches the new article, it avoids obvious 404 problems.&lt;/p&gt;
&lt;h2 id=&#34;when-to-consider-server-side-redirects&#34;&gt;When to consider server-side redirects
&lt;/h2&gt;&lt;p&gt;If your site is hosted on Netlify, Cloudflare Pages, Vercel, or another platform that supports redirect rules, server-side redirects may be a better option.&lt;/p&gt;
&lt;p&gt;Server-side redirects have several advantages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;They respond more directly without returning an intermediate HTML redirect page.&lt;/li&gt;
&lt;li&gt;They make it easier to use explicit 301 or 302 status codes.&lt;/li&gt;
&lt;li&gt;They centralize large migration rule sets for easier review and maintenance.&lt;/li&gt;
&lt;li&gt;They give you more control over SEO migrations.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A common approach is to disable Hugo&amp;rsquo;s default alias page generation and output the redirect rules required by the hosting platform instead. Netlify commonly uses &lt;code&gt;_redirects&lt;/code&gt;; Cloudflare Pages can use &lt;code&gt;_redirects&lt;/code&gt; or platform-level rules.&lt;/p&gt;
&lt;p&gt;If you choose this route, study Hugo&amp;rsquo;s &lt;code&gt;disableAliases&lt;/code&gt; setting and custom output formats. Do not simply remove &lt;code&gt;aliases&lt;/code&gt;, or the old links will turn into 404s.&lt;/p&gt;
&lt;h2 id=&#34;things-to-watch-out-for&#34;&gt;Things to watch out for
&lt;/h2&gt;&lt;p&gt;First, do not use &lt;code&gt;aliases&lt;/code&gt; as an excuse to change URLs casually.&lt;/p&gt;
&lt;p&gt;Once a URL is public, it enters search engines, RSS feeds, social platforms, bookmarks, and external references. Frequent URL changes create maintenance costs. &lt;code&gt;aliases&lt;/code&gt; are better for fixing historical problems than for encouraging constant path changes.&lt;/p&gt;
&lt;p&gt;Second, avoid redirect loops.&lt;/p&gt;
&lt;p&gt;Old addresses should point to the current page&amp;rsquo;s new address. Do not make A redirect to B while B redirects back to A, and do not let multiple pages claim the same alias.&lt;/p&gt;
&lt;p&gt;Third, be careful with language prefixes on multilingual sites.&lt;/p&gt;
&lt;p&gt;Hugo multilingual sites often handle language paths automatically. If you write an alias inside a language-specific version, you may not need to manually add prefixes such as &lt;code&gt;/en/&lt;/code&gt; or &lt;code&gt;/zh-tw/&lt;/code&gt;. Otherwise, you may generate duplicated paths such as &lt;code&gt;/en/en/...&lt;/code&gt;. Always verify the local build result.&lt;/p&gt;
&lt;p&gt;Fourth, check the generated output after changes.&lt;/p&gt;
&lt;p&gt;After adding an alias, build the site and check whether the old path&amp;rsquo;s &lt;code&gt;index.html&lt;/code&gt; appears under &lt;code&gt;public&lt;/code&gt;. Also confirm that the redirect target inside that file is correct.&lt;/p&gt;
&lt;h2 id=&#34;a-practical-check-workflow&#34;&gt;A practical check workflow
&lt;/h2&gt;&lt;p&gt;After editing the article Front Matter:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Confirm the current article&amp;rsquo;s new URL.&lt;/li&gt;
&lt;li&gt;Add the old URL to &lt;code&gt;aliases&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run a Hugo build.&lt;/li&gt;
&lt;li&gt;Check whether &lt;code&gt;public&lt;/code&gt; contains the old URL&amp;rsquo;s &lt;code&gt;index.html&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Open the generated HTML and confirm that it redirects to the new URL.&lt;/li&gt;
&lt;li&gt;For multilingual pages, check especially for duplicated language prefixes.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This catches most path mistakes before deployment.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;aliases&lt;/code&gt; are Hugo&amp;rsquo;s lightweight tool for preserving old links.&lt;/p&gt;
&lt;p&gt;They are best suited for article URL changes, blog migrations, page merges, and incorrect-path fixes. Ordinary static sites can directly use Hugo&amp;rsquo;s default HTML redirect pages. Larger sites, or sites with stricter SEO migration requirements, can move further toward server-side redirect rules.&lt;/p&gt;
&lt;p&gt;The real point is not only making new URLs look cleaner. It is also taking care of old URLs that already exist. A site that smoothly carries old URLs to new pages is much less likely to lose historical traffic during migrations and redesigns.&lt;/p&gt;
&lt;h2 id=&#34;references&#34;&gt;References
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://gohugo.io/content-management/urls/#aliases&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hugo Documentation: Aliases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://gohugo.io/content-management/urls/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hugo Documentation: URL management&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        
    </channel>
</rss>
