This is the multi-page printable view of this section. Click here to print.
Deployment and previews
- 1: Deployment with Amazon S3 and CloudFront
- 2: Deployment on GitHub Pages
- 3: Serving your site locally
- 4: Deployment on Netlify
- 5: Page chrome
There are multiple possible options for deploying a Hugo site, including Netlify, Firebase Hosting, Bitbucket with Aerobatic, and more; you can read about them all in Hosting and Deployment. Hugo also makes it easy to deploy your site locally for quick previews of your content.
Build environments and indexing
By default, Hugo sites built with hugo (rather than served locally with
hugo server) have the Hugo build environment production. Deployed Docsy
sites with production builds can be indexed by search engines, including
Google Custom Search Engines. Production
builds also have optimized JavaScript and CSS for live deployment (for example,
minified JS rather than the more legible original source).
If you do not want your deployed site to be indexed by search engines (for
example if you are still developing your live site), or if you want to build a
development version of your site for offline analysis, you can set your Hugo
build environment to something else such as development (the default for local
deploys with hugo server), test, or another environment name of your choice.
The simplest way to set this is by using the -e flag when specifying or
running your hugo command, as in the following example:
hugo -e development
1 - Deployment with Amazon S3 and CloudFront
There are several options for publishing your web site using Amazon Web Services. This section describes the most basic option, deploying your site using an S3 bucket and activating the CloudFront CDN (content delivery network) to speed up the delivery of your deployed contents.
-
After your registration at AWS, create your S3 bucket, connect it with your domain, and add it to the CloudFront CDN. This blog post has all the details and provides easy to follow step-by-step instructions for the whole procedure.
-
Download and install the latest version 2 of the AWS Command Line Interface (CLI). Then configure your CLI instance by issuing the command
aws configure(make sure you have your AWS Access Key ID and your AWS Secret Access Key at hand):$ aws configure AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY Default region name [None]: eu-central-1 Default output format [None]: -
Check the proper configuration of your AWS CLI by issuing the command
aws s3 ls, this should output a list of your S3 bucket(s).
-
Inside your
hugo.toml/hugo.yaml/hugo.json, add a[deployment]section like this one:[deployment] [[deployment.targets]] name = "aws" URL = "s3://www.your-domain.tld" cloudFrontDistributionID = "E9RZ8T1EXAMPLEID"deployment: targets: - name: aws URL: 's3://www.your-domain.tld' cloudFrontDistributionID: E9RZ8T1EXAMPLEID{ "deployment": { "targets": [ { "name": "aws", "URL": "s3://www.your-domain.tld", "cloudFrontDistributionID": "E9RZ8T1EXAMPLEID" } ] } }
-
Run the command
hugo --gc --minifyto render the site’s assets into thepublic/directory of your Hugo build environment. -
Use Hugo’s built-in
deploycommand to deploy the site to S3:hugo deploy Deploying to target "aws" (www.your-domain.tld) Identified 77 file(s) to upload, totaling 5.3 MB, and 0 file(s) to delete. Success! Invalidating CloudFront CDN... Success!As you can see, issuing the
hugo deploycommand automatically invalidates your CloudFront CDN cache. -
That’s all you need to do! From now on, you can easily deploy to your S3 bucket using Hugo’s built-in
deploycommand!
For more information about the Hugo deploy command, including command line
options, see this synopsis. In
particular, you may find the --maxDeletes int option or the --force option
(which forces upload of all files) useful.
If the source of your site lives in a GitHub repository, you can use GitHub Actions to deploy the site to your S3 bucket as soon as you commit changes to your GitHub repo. Setup of this workflow is described in this blog post.
If S3 does not meet your needs, consider AWS Amplify Console. This is a more advanced continuous deployment (CD) platform with built-in support for the Hugo static site generator. A starter can be found in Hugo’s official docs.
2 - Deployment on GitHub Pages
If your source is hosted on GitHub, GitHub Pages can build and publish the site with a single Actions workflow. The consuming site needs Hugo Extended but does not need Node.js, npm, PostCSS, or a generated deployment branch.
Project sites use a URL such as https://<OWNER>.github.io/<REPOSITORY>/; user
and organization sites use https://<OWNER>.github.io/. Custom domains are also
supported.
Prepare the repository
Push the complete site source to GitHub and confirm that this command succeeds from the repository root:
hugo --gc --minify
Set the site’s baseURL to its production URL, or pass the Pages URL with
Hugo’s --baseURL option in the workflow. A project site must include the
repository path; otherwise CSS, JavaScript, and other resources will resolve
from the wrong location.
Add the Pages workflow
Create .github/workflows/pages.yml with the following contents. Keep
HUGO_VERSION aligned with a version validated by the theme.
name: Deploy Hugo site to Pages
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: false
env:
GO_VERSION: 1.25.5
HUGO_VERSION: 0.164.0
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
submodules: recursive
- uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
- name: Install Hugo Extended
run: |
curl -L -o hugo.deb \
"https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb"
sudo dpkg -i hugo.deb
- uses: actions/configure-pages@v6
id: pages
- name: Build
run: >-
hugo --gc --minify --baseURL "${{ steps.pages.outputs.base_url }}/"
- uses: actions/upload-pages-artifact@v5
with:
path: public
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy
id: deployment
uses: actions/deploy-pages@v5
If the theme is installed as a Git submodule, submodules: recursive checks it
out before Hugo runs. A complete offline archive can instead commit or restore
the adjacent theme/ directory as part of the repository or build input.
Enable GitHub Pages
In the repository settings, open Pages. Under Build and deployment, set
Source to GitHub Actions. Push the workflow to main, then follow its
first run in the repository’s Actions tab.
The workflow uploads only the generated public/ directory and publishes it
through the Pages deployment API. It does not maintain a gh-pages branch.
For other authentication, domain, and permission options, see GitHub’s Pages documentation and Hugo’s GitHub hosting guide.
3 - Serving your site locally
Depending on your deployment choice you may want to serve your site locally during development to preview content changes. To serve your site locally:
-
Ensure you have an up to date local copy of your site files cloned from your repo.
-
Ensure Hugo Extended and any source-fetch tools required by your chosen installation method are installed, as described in Prerequisites and installation. Node.js and PostCSS are not site-build prerequisites.
-
Run the
hugo servercommand in your site root. By default your site will be available at http://localhost:1313.
Now that you’re serving your site locally, Hugo will watch for changes to the content and automatically refresh your site. If you have more than one local git branch, when you switch between git branches the local website reflects the files in the current branch.
4 - Deployment on Netlify
Netlify can build a site from GitHub, GitLab, or Bitbucket and publish a preview for each pull request. An OINK consumer build runs Hugo Extended directly; it does not install Node.js packages or invoke PostCSS.
Configure the site
Push the complete source to your Git provider, import the repository in Netlify, and use these build settings:
| Setting | Value |
|---|---|
| Build command | hugo --gc --minify |
| Publish directory | public |
HUGO_VERSION |
0.164.0 or another theme-validated version |
If Netlify detects package manifests that exist only for theme-maintainer tooling, disable automatic dependency installation for the site. They are not part of the consumer build contract.
For a theme installed as a Git submodule, enable recursive submodule checkout.
For a Hugo module, Netlify also needs the normal Git and Go access required to
download the pinned module on a clean build. A complete offline distribution
uses the adjacent theme/ directory and avoids that first-build download.
Keep configuration in the repository
The same settings can be committed as netlify.toml:
[build]
command = "hugo --gc --minify"
publish = "public"
[build.environment]
HUGO_VERSION = "0.164.0"
Keep production and deploy-preview contexts on the same Hugo version unless a preview is intentionally testing an upgrade. If preview builds need their generated URL as the base URL, add Netlify’s deploy URL to the Hugo command for that context.
To prevent a non-production deployment from being indexed, use a non-production Hugo environment as described in Build environments and indexing.
After saving the settings, trigger a deploy and inspect the build log. A normal consumer build should show one Hugo command and no npm, PostCSS, Autoprefixer, CDN download, or build-time remote-resource step.
5 - Page chrome
The theme renders the complete navbar, sidebar, table of contents, search entry, and footer in each applicable page. This is the canonical production structure for normal builds, previews, offline archives, search crawlers, and clients without JavaScript.
The experimental upstream td.chrome = shared donor/restoration mode is not
part of this theme. The params.td.chrome setting has no effect and should be
removed from migrated site configuration. Keeping one server-rendered structure
avoids a second visual implementation and keeps navigation, language selection,
accessibility semantics, and offline behavior deterministic.
Use Hugo minification and hosting-layer compression to reduce transfer size:
hugo --gc --minify
The interactive shell script enhances the already rendered markup; it is not required to reconstruct missing navigation regions.