Preflight – what it checks and why

Catch broken paths, configuration and assets before they reach the published site.

Last updated

A local Hugo build can look fine and still break after deployment. Preflight checks the paths, configuration and assets before every publish.

HugoKit's preflight report: the pre-publish checks, with a fix offered as a red and green diff to approve.

When it runs

Preflight runs automatically before publishing. A clean report continues to the publish; findings open the report first.

You can also run it on its own with ⇧⌘P.

What it checks

#StepLooks for
1Hugo buildDoes the site build at all? Errors and warnings are translated into plain language.
2ConfigStructural problems in hugo.toml – keys at the wrong level, empty sections.
3baseURLMissing, pointing at localhost, not matching where the site actually deploys, missing its trailing slash.
4AssetsEvery CSS, JS, font and image the built HTML asks for – is the file actually in public/?
5TemplatesHardcoded absolute paths in your layouts and theme.
6Deploy configAn Actions workflow that contradicts the publishing mode you chose.
7Static JavaScriptHardcoded paths inside JS files in static/ – the files Hugo never processes.

If the build fails, Preflight stops because the remaining checks require completed build output.

Steps 5 and 7 run only for subpath deployments, such as you.github.io/my-blog/, where root-relative paths can point outside the site.

Errors block, warnings don’t

Every issue is an error, a warning or info.

Errors must be resolved before publishing. Warnings are reported but do not block the publish.

Fixes are a diff you approve

When a finding has an automatic fix, Fix Preview shows the affected files and line changes. Apply writes the approved change, then Preflight runs again.

Applied fixes also go through the app’s snapshot layer: every file a fix touches is copied first, and the change can be undone – file by file or all at once. See Snapshots and undo.

What it can fix, and what the fix does:

FindingThe fix
Hardcoded asset paths in templatesA leading slash – /js/app.js – becomes {{ "js/app.js" | relURL }}, and Hugo adds the subpath for you.
Dynamic paths missing relURLPaths built inside templates (printf "/img/%s.svg", dict "url" "/thoughts/") get the same treatment.
Hardcoded paths in static JSInjects window.__basePath into your head template, then rewrites fetch('/index.json') to go through it. Hugo doesn’t process static/, so this is the only way.
baseURL missing, localhost, or wrongSets it to the URL the site actually deploys to.
Missing asset filesRemoves the tags pointing at files that don’t exist.
Raw HTML omitted from MarkdownAdds ignoreLogs for Goldmark’s raw-HTML warning.
Actions workflow vs. gh-pages conflictRemoves the workflow and switches Pages to the branch you’re actually pushing to.

Findings without an automatic fix include the file location and a suggested manual change.

Why relURL and not just a path

Hugo’s relURL ignores anything that starts with /. That’s the whole trap:

In your templateOutput on /my-blog/
{{ "/img/logo.svg" | relURL }}/img/logo.svg – unchanged, and broken
{{ "img/logo.svg" | relURL }}/my-blog/img/logo.svg – correct

So every fix strips the leading slash before piping through relURL. If you’re fixing this by hand, that’s the rule to remember.

It checks the paths your site emits – assets, templates, scripts. For broken links between your pages, word counts, front matter quality and a build trend, that’s Site Health (⇧⌘H), which is a different tool with a different job.

Latest release · 9 August 2026

HugoKit 0.4.0

Adds search, find and replace, an outline, backlinks and page resources to the editor, and shows what a publish will change before it happens.

  • 01 Find and replaceSearch the Content list, then find and replace inside the open Raw document.
  • 02 Page resourcesThe files in a page's bundle, with Quick Look and insert-a-reference.
  • 03 Review ChangesSee what publishing would add, change and delete on each target.