Install Hugo's Zsh Completion Without Guesswork
You will generate Hugo's completion script, test it in the current Zsh session, then install it for future sessions. This guide uses Hugo 0.123.7, installed from Ubuntu's hugo package. Allow about ten minutes. You need Hugo, Zsh, and permission to write either your Zsh configuration or a completion directory. Zsh is not installed in the reference environment, so the shell-session checks below must be run on a machine with Zsh available.
The route
Jump straight to the step you need, or tick off Done means at the end.
The completion script only improves command-line suggestions. It does not change a Hugo site, build output, configuration file, or service. The permanent setup does change shell startup or a completion file, so the examples show how to inspect the destination first.
1. Confirm the installed Hugo and Zsh
Check Hugo first, then verify that Zsh is available. These are ordinary, read-only commands:
$ hugo version
hugo v0.123.7+extended linux/amd64 BuildDate=2026-03-17T19:51:14Z VendorInfo=ubuntu:0.123.7-1ubuntu0.3+esm2
$ command -v zsh
/path/to/zsh
The path is host-specific. If command -v zsh prints nothing, install Zsh through your distribution's normal package manager before continuing. The important Hugo check is that it resolves to the installation you intend to use. If it does not, fix your PATH before generating completion data.
Checkpoint: ask the installed command for its exact completion options:
$ hugo completion zsh --help
Generate the autocompletion script for the zsh shell.
Usage:
hugo completion zsh [flags]
2. Load completion for one shell session
Test the generated script without writing a file. Start Zsh, enable its completion system, and source Hugo's output through process substitution:
$ zsh
% autoload -U compinit
% compinit
% source <(hugo completion zsh)
% hugo <TAB>
After pressing Tab, Zsh should offer Hugo subcommands such as build, completion, config, new, server, and version. The exact display depends on your Zsh completion style.
This test is temporary. The generated script is read into the current shell and is not saved. Leave the test shell with exit when you are done:
% exit
$
If compinit is not available, install the Zsh package that provides it through your distribution's normal package manager. Do not treat a missing completion function as a Hugo failure.
3. Enable completion in new Zsh sessions
For a normal user setup, add Zsh's completion initialisation to ~/.zshrc once:
$ grep -qxF 'autoload -U compinit; compinit' ~/.zshrc || \
printf '%s\n' 'autoload -U compinit; compinit' >> ~/.zshrc
$ tail -n 3 ~/.zshrc
autoload -U compinit; compinit
The guard prevents duplicate lines. This writes to your home directory, but it does not need sudo. If you do not want to edit startup configuration, keep using the session-only command from step 2.
To undo this particular change, open ~/.zshrc and remove the exact line added above. Do not delete other compinit settings that may belong to your existing Zsh configuration.
4. Install Hugo's completion file in an fpath directory
Start a fresh Zsh session so fpath is populated, then inspect its directories:
$ zsh -ic 'print -l $fpath'
/home/EXAMPLE/.zfunc
/usr/local/share/zsh/site-functions
/usr/share/zsh/vendor-functions
/usr/share/zsh/functions
Choose a directory that exists and is writable by your user. The first entry is commonly a user-owned directory, but do not assume that from the name. Check it explicitly:
$ COMPLETION_DIR="${fpath[1]}"
$ test -d "$COMPLETION_DIR" && test -w "$COMPLETION_DIR"
$ printf 'completion directory: %s\n' "$COMPLETION_DIR"
completion directory: /home/EXAMPLE/.zfunc
If the check fails, stop and choose another existing writable directory. Creating a directory inside your home is ordinary user-level work:
$ mkdir -p "$HOME/.zfunc"
$ COMPLETION_DIR="$HOME/.zfunc"
$ hugo completion zsh > "$COMPLETION_DIR/_hugo"
$ chmod 0644 "$COMPLETION_DIR/_hugo"
$ wc -l "$COMPLETION_DIR/_hugo"
1234 /home/EXAMPLE/.zfunc/_hugo
The line count is illustrative and can change between Hugo versions. Verify the file is a Zsh completion script rather than an error message:
$ sed -n '1,2p' "$COMPLETION_DIR/_hugo"
#compdef hugo
compdef _hugo hugo
If you selected a system directory such as /usr/share/zsh/vendor-functions and it is not writable, installation there requires elevated privileges. Prefer a user-owned directory where your Zsh setup already includes it in fpath; use sudo only when your distribution's package layout requires the system location.
5. Start a new shell and verify the installed file
Open a new Zsh shell so it reads ~/.zshrc, then check that the completion function is loaded:
$ exec zsh
% whence -f _hugo
_hugo () {
# completion function body varies by Hugo version
}
% hugo <TAB>
whence -f _hugo confirms that Zsh found the function. Tab completion confirms that the function is attached to the hugo command. If the function is found but Tab shows nothing, inspect the generated file and run compinit again in the new shell.
Hugo also accepts --no-descriptions when you want suggestions without completion descriptions:
$ hugo completion zsh --no-descriptions > "$COMPLETION_DIR/_hugo"
$ head -n 2 "$COMPLETION_DIR/_hugo"
#compdef hugo
compdef _hugo hugo
This replaces the completion file, so keep the command only if that is the display you want. To restore descriptions, regenerate it without --no-descriptions. No Hugo project files are involved.
6. Diagnose the usual failures
If hugo completion zsh prints help instead of a script, check that zsh is the subcommand and that the command is spelled exactly as shown. If the file begins with an error, remove it and rerun the command after fixing Hugo or its PATH.
If completion disappears after restarting the shell, check three separate layers: ~/.zshrc ran compinit, the directory containing _hugo appears in fpath, and _hugo is readable. A valid generated file in a directory that Zsh does not search will not be loaded.
To remove the installed completion without affecting Hugo, delete only the file you created after checking its path:
$ printf 'remove only: %s\n' "$COMPLETION_DIR/_hugo"
remove only: /home/EXAMPLE/.zfunc/_hugo
$ rm -- "$COMPLETION_DIR/_hugo"
This is the only destructive command in the guide. Do not run it with an unresolved variable or against a directory. Start a new Zsh session afterwards, and remove the startup line only if you added it for this setup.
Done means
hugo versionreports the intended installation.hugo completion zshproduces a file beginning with#compdef hugo.- Completion works in a test shell before permanent installation.
compinitruns once from your Zsh startup configuration._hugois in a readable directory listed byfpath.- A new Zsh session finds
_hugoand offers Hugo commands on Tab.