跳到主要内容

hugo部署到cloudflare页面显示错误问题

问题的起因

最近想翻译cloudflare的文档,也就是这个:cloudflare-docs

他们的这个文档是基于hugo搭建的,git clone然后直接部署到cloudflare之后,发现主页显示没问题,但是其他页面样式会错误。仿佛css没有加载一样

但是使用浏览器调试发现所有的css都有加载, 而且打开官方的网址对比发现加载是没问题。

问题解决

使用relativeURLs = true

在谷歌上搜索hugo样式错误的解决办法都是一些零星琐碎的,但是其中这个issues和我碰到的问题非常相似:关于页面样式和路径的问题

当中提到的这一句,几乎以为让我找到解决办法

但是在我对config.toml增加配置relativeURLs = true,并且使用hugo -D后,打开后的页面问题和部署在cloudflare上的问题是一样的。

比较npm run devhugo -D 生成的文件

我突然想到既然使用npm run dev是显示正常的,而hugo -D 构建生成文件打开样式错误,那么直接对比两者生成的html不就是最好的办法吗!

还真就是这个办法解决了我的问题:

通过对比可以发现两者在加载这段style.css时明显不一样

npm run dev

<link rel="stylesheet preconnect" href="../style.css" />
<link rel="stylesheet preconnect" href="../codeBlock.css" />

hugo -D

<link rel="preload" href="../style.css" as="style" />
<link rel="preload" href="../codeBlock.css" as="style" />

因为我对前端知识的不熟悉,只能请ChatGPT出马了

这里把ChatGPT的回复搬过来:

ChatGPT

A版本和B版本的主要区别在于样式表的加载方式。为了理解为什么A版本生效而B版本没有,我们需要分析这两个版本中每个标签的作用及其在浏览器中的行为。

A版本

<link rel="apple-touch-icon" sizes="512x512" href="../icons/icon-512x512.png" />
<link rel="stylesheet preconnect" href="../style.css" />
<link rel="stylesheet preconnect" href="../codeBlock.css" />
<link rel="preload" href="https://unpkg.com/[email protected]/dist/littlefoot.css" as="style">

B版本

<link rel="apple-touch-icon" sizes="512x512" href="../icons/icon-512x512.png" />
<link rel="preload" href="../style.css" as="style" />
<link rel="preload" href="../codeBlock.css" as="style" />
<link rel="preload" href="https://unpkg.com/[email protected]/dist/littlefoot.css" as="style">

关键区别分析

A版本

  • <link rel="stylesheet preconnect" href="../style.css" />
  • rel="stylesheet" 用于引入样式表,这使得浏览器会立即加载并应用这个样式表。
  • preconnect 在这里是不正确的使用,因为 preconnect 是用于建立早期连接的提示,但它在 rel="stylesheet" 的标签中是无效的。

B版本

  • <link rel="preload" href="../style.css" as="style" />
  • rel="preload" 只是提示浏览器预加载资源,但不会应用这些资源。
  • 需要一个额外的 标签来实际应用样式。

为什么A版本生效而B版本没有

样式表加载和应用:

在A版本中,<link rel="stylesheet" href="../style.css" /> 会立即加载和应用样式表。这确保了页面在加载时可以正确地应用这些样式。 在B版本中,<link rel="preload" href="../style.css" as="style" /> 只是预加载样式表,但不会自动应用这些样式。这意味着样式表虽然被预加载了,但没有被应用到页面上。 正确的标签使用:

A版本尽管错误地使用了 preconnect,但 rel="stylesheet" 保证了样式表会被应用。 B版本只使用了 rel="preload",因此样式表被预加载但未应用。 正确的B版本(假设要预加载并应用样式) 为了让B版本也能生效,可以改成如下:

<link rel="apple-touch-icon" sizes="512x512" href="../icons/icon-512x512.png" />
<link rel="preload" href="../style.css" as="style" />
<link rel="preload" href="../codeBlock.css" as="style" />
<link rel="preload" href="https://unpkg.com/[email protected]/dist/littlefoot.css" as="style" />
<link rel="stylesheet" href="../style.css" />
<link rel="stylesheet" href="../codeBlock.css" />
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/littlefoot.css" />

这样做可以保证样式表被预加载,同时也会被正确地应用。

你别说,改完后立马就生效了。

最后还得问问为什么hugo会生成错误的html?

ChatGPT

如果B版本是由Hugo自动生成的,这确实可能是Hugo配置中的问题或模板文件的设置问题。rel="preload" 只是预加载资源,而不会应用这些资源。要解决这个问题,需要确保生成的HTML包含正确的<link rel="stylesheet">标签,以便样式表能够实际应用。

解决方案

  1. 检查Hugo配置和模板文件 你需要检查你的Hugo配置文件(通常是config.tomlconfig.yaml)和模板文件,以确保它们生成正确的HTML标签。

  2. 修改Hugo模板文件 如果你使用的是自定义主题或模板,可以在模板文件中手动添加正确的<link rel="stylesheet">标签。

举例:假设你的模板文件位于layouts/partials/head.html,可以进行如下修改:

<!-- 添加预加载标签 -->
<link rel="preload" href="{{ "style.css" | relURL }}" as="style">
<link rel="preload" href="{{ "codeBlock.css" | relURL }}" as="style">
<link rel="preload" href="https://unpkg.com/[email protected]/dist/littlefoot.css" as="style">

<!-- 添加实际应用样式的标签 -->
<link rel="stylesheet" href="{{ "style.css" | relURL }}">
<link rel="stylesheet" href="{{ "codeBlock.css" | relURL }}">
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/littlefoot.css">

最后的最后,使用全局搜索rel="preload",就找到了加载css的代码位置

稍作修改便完美解决。

    {{- if hugo.IsProduction -}}
<!-- 在生产环境中,预加载并实际应用样式表 -->
<link rel="preload" href="/style.css" as="style" />
<link rel="preload" href="/codeBlock.css" as="style" />
<link rel="stylesheet" href="/style.css" />
<link rel="stylesheet" href="/codeBlock.css" />
{{- else -}}
<!-- 在非生产环境中,直接应用样式表 -->
<link rel="stylesheet" href="/style.css" />
<link rel="stylesheet" href="/codeBlock.css" />
{{- end -}}