> **New in 2026 — managed Static Hosting**: DeployHQ now offers [Static Hosting](https://www.deployhq.com/hosting/static) — fully-managed deployment to Cloudflare's edge for Hugo and other static-site generators, no server to provision. The walkthrough below covers BYO-server deployment, which remains fully supported.

**Prerequisites:**

- A server with SSH or SFTP access (VPS, dedicated, or shared hosting)
- A Hugo project in a Git repository
- A DeployHQ account

## What is Hugo?

Hugo is a static site generator written in Go. It's the fastest SSG available — building thousands of pages in under a second — and ships as a single binary with zero dependencies. No Node.js runtime, no Ruby, no Python. Just download the binary and run it.

Hugo powers documentation sites, blogs, marketing pages, and portfolios. Its templating system is based on Go's `html/template` package, and it supports content organisation through taxonomies, sections, and archetypes.

Hugo has over 80,000 GitHub stars and a mature ecosystem of themes and modules.

## Step 1: Install Hugo

**macOS (Homebrew):**
```bash
brew install hugo
```

**Ubuntu/Debian:**
```bash
sudo apt install hugo
```

**Binary download (any platform):**
```bash
# Download the extended version (includes SCSS support)
curl -sL https://github.com/gohugoio/hugo/releases/download/v0.145.0/hugo_extended_0.145.0_linux-amd64.tar.gz | tar xz
sudo mv hugo /usr/local/bin/
```

Always use the **extended** version. The standard version lacks SCSS/SASS compilation, which most themes require.

Verify installation:
```bash
hugo version
# hugo v0.145.0-extended ...
```

## Step 2: Create a Hugo Site

```bash
hugo new site my-site
cd my-site
```

Add a theme (most Hugo sites use one):
```bash
git init
git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke themes/ananke
```

Configure the theme in `hugo.toml`:
```toml
baseURL = 'https://example.com/'
languageCode = 'en-gb'
title = 'My Site'
theme = 'ananke'
```

Create your first post:
```bash
hugo new content posts/my-first-post.md
```

Start the development server:
```bash
hugo server -D
```

The site is available at `http://localhost:1313` with live reload.

## Step 3: Project Structure

```
my-site/
├── archetypes/          # Content templates for hugo new
│   └── default.md
├── assets/              # Files processed by Hugo Pipes (SCSS, JS)
├── content/             # Markdown content files
│   └── posts/
│       └── my-first-post.md
├── data/                # Data files (JSON, YAML, TOML)
├── i18n/                # Translation strings
├── layouts/             # Template files
│   ├── _default/
│   │   ├── baseof.html
│   │   ├── list.html
│   │   └── single.html
│   └── partials/
├── static/              # Static files copied as-is (favicon, robots.txt)
├── themes/              # Theme directory (usually Git submodules)
│   └── ananke/
├── hugo.toml            # Site configuration
└── go.mod               # Hugo module dependencies (optional)
```

### Key Directories

- **content/** — Markdown files with YAML/TOML front matter. Directory structure maps to URL structure.
- **layouts/** — Go templates. Override theme templates by placing files with the same path here.
- **assets/** — Files that Hugo processes (SCSS compilation, image resizing, JS bundling).
- **static/** — Files copied verbatim to `public/`. Use for favicons, `robots.txt`, pre-built assets.
- **themes/** — Installed themes. Typically Git submodules.

## Step 4: Configuration

Hugo supports `hugo.toml`, `hugo.yaml`, or `hugo.json`. TOML is the convention.

```toml
baseURL = "https://example.com/"
languageCode = "en-gb"
title = "My Hugo Site"
theme = "ananke"

[params]
  description = "A Hugo site deployed with DeployHQ"
  author = "Your Name"

[markup]
  [markup.goldmark]
    [markup.goldmark.renderer]
      unsafe = true  # Allow raw HTML in markdown

[outputs]
  home = ["HTML", "RSS", "JSON"]  # Enable JSON for search

[minify]
  disableCSS = false
  disableHTML = false
  disableJS = false
  disableJSON = false
  disableSVG = false
  disableXML = false
```

### Environment-Specific Configuration

Hugo supports configuration directories for per-environment settings:

```
config/
├── _default/
│   └── hugo.toml        # Base configuration
├── production/
│   └── hugo.toml        # Production overrides
└── staging/
    └── hugo.toml        # Staging overrides
```

Build with a specific environment:
```bash
hugo --minify --environment production
```

## Step 5: Core Features

### Content Management

Hugo content uses front matter for metadata:

```markdown
---
title: "My Post Title"
date: 2026-03-07
draft: false
tags: ["deployment", "hugo"]
categories: ["tutorials"]
description: "A brief description for SEO"
---

Post content in Markdown here.
```

### Taxonomies

Hugo supports taxonomies (tags, categories, or custom):

```toml
[taxonomies]
  tag = "tags"
  category = "categories"
  series = "series"
```

### Shortcodes

Reusable content snippets:

```markdown
{{< youtube dQw4w9WgXcQ >}}
{{< figure src="/images/photo.jpg" caption="A photo" >}}
```

### Hugo Pipes (Asset Processing)

Process SCSS, fingerprint assets, and minify in templates:

```html
{{ $style := resources.Get "scss/main.scss" | toCSS | minify | fingerprint }}
<link rel="stylesheet" href="{{ $style.RelPermalink }}" integrity="{{ $style.Data.Integrity }}">
```

### Image Processing

Hugo can resize and convert images at build time:

```html
{{ $image := resources.Get "images/hero.jpg" }}
{{ $small := $image.Resize "600x webp" }}
<img src="{{ $small.RelPermalink }}" alt="Hero" width="{{ $small.Width }}" height="{{ $small.Height }}">
```

### Multilingual Support

```toml
defaultContentLanguage = "en"

[languages]
  [languages.en]
    title = "My Site"
    weight = 1
  [languages.fr]
    title = "Mon Site"
    weight = 2
```

Content is organised per-language: `content/en/posts/` and `content/fr/posts/`.

## Step 6: Build for Production

```bash
hugo --minify
```

Output goes to `public/`:

```
public/
├── index.html
├── index.xml           # RSS feed
├── sitemap.xml
├── posts/
│   ├── index.html      # List page
│   └── my-first-post/
│       └── index.html  # Single page
├── tags/
├── categories/
├── css/
├── js/
└── images/
```

Hugo generates clean URLs by default: `/posts/my-first-post/` serves `posts/my-first-post/index.html`.

Build statistics:
```bash
hugo --minify --printPathWarnings --printUnusedTemplates
```

## Step 7: Deploy with DeployHQ

### Create a DeployHQ Project

1. Sign up at [deployhq.com](https://www.deployhq.com/signup)
2. Create a new project and connect your Git repository
3. DeployHQ automatically installs a webhook for push-triggered deployments

### Configure the Build Command

Hugo is a Go binary, not a Node.js package. The build command needs to download Hugo on the build server:

```bash
cd %path% && curl -sL https://github.com/gohugoio/hugo/releases/download/v0.145.0/hugo_extended_0.145.0_linux-amd64.tar.gz | tar xz && ./hugo --minify
```

**Important:** Use `hugo_extended` if your theme uses SCSS. The standard version will fail silently or with a cryptic error.

**Pin the Hugo version.** Hugo occasionally introduces breaking changes. Update the version in your build command deliberately, not automatically.

### Set the Deployment Subdirectory

```
public
```

This ensures only the built static files are deployed — not your Hugo source code, themes, or content markdown.

### Configure Your Server

- **Protocol:** SSH (recommended) or SFTP
- **Hostname:** Your server IP or domain
- **Deployment Path:** `/var/www/hugo-site/`
- **Authentication:** SSH key

### Git Submodules for Themes

DeployHQ supports **recursive submodule checkout**. If your theme is a Git submodule, it's cloned automatically during deployment. No extra configuration needed.

Verify your `.gitmodules` file is committed:
```ini
[submodule "themes/ananke"]
    path = themes/ananke
    url = https://github.com/theNewDynamic/gohugo-theme-ananke.git
```

### Server Configuration (Nginx)

```nginx
server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    root /var/www/hugo-site;
    index index.html;

    # Static assets
    location ~* \.(css|js|png|jpg|jpeg|gif|svg|ico|woff|woff2)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # HTML pages
    location / {
        try_files $uri $uri/ $uri/index.html =404;
        expires 1h;
        add_header Cache-Control "public, must-revalidate";
    }

    error_page 404 /404.html;
}
```

No PM2 or process manager needed — Hugo sites are pure static files.

### Branch-Based Environments

| Branch | Server | Build Flag |
|--------|--------|------------|
| `main` | production | `./hugo --minify --environment production` |
| `staging` | staging | `./hugo --minify --environment staging --baseURL https://staging.example.com/` |

### Deploy

Push a commit. DeployHQ:
1. Clones your repo (with theme submodules)
2. Downloads Hugo binary and builds the site
3. Compares `public/` against what's on the server
4. Transfers only the changed files via SSH/SFTP

Edit one blog post? Hugo rebuilds in milliseconds. DeployHQ transfers ~3-4 files (the post, the list page, RSS feed, sitemap). Deployment completes in seconds.

## Step 8: Troubleshooting

### "TOCSS: ... this feature is not available in your current Hugo version"

You're using the standard Hugo binary instead of the extended version. Update your build command to download `hugo_extended`:

```bash
curl -sL https://github.com/gohugoio/hugo/releases/download/v0.145.0/hugo_extended_0.145.0_linux-amd64.tar.gz | tar xz
```

### Theme Not Found

Ensure the theme is either:
- A Git submodule (check `.gitmodules` is committed)
- Or committed directly in the `themes/` directory

If using submodules, verify the URL in `.gitmodules` is accessible from DeployHQ's build server.

### Wrong baseURL in Production

Links and assets point to `localhost` or the wrong domain. Set the correct `baseURL` in `hugo.toml` or override it in the build command:

```bash
./hugo --minify --baseURL "https://example.com/"
```

### Build Works Locally But Fails on DeployHQ

Check Hugo version mismatch. Your local Hugo might be newer or older than the version in the build command. Pin the same version in both.

Also check for OS-specific issues — if you develop on macOS but deploy from Linux, ensure your theme doesn't use case-sensitive file paths incorrectly.

### Submodule Cloning Fails

If the theme repository is private, the DeployHQ SSH key needs access to both your main repo and the theme repo. Either:
- Make the theme repo public
- Add the DeployHQ key to the theme repo as a deploy key
- Use HTTPS with embedded credentials in `.gitmodules`

## Conclusion

Hugo's build speed is legendary, and pairing it with DeployHQ's differential deployment means your content goes live seconds after pushing. The `public/` directory contains pure static files — no server runtime, no process manager, no database. Just HTML, CSS, and JavaScript served by Nginx.

For other frameworks, browse the full [DeployHQ guides library](https://www.deployhq.com/guides).

Ready to automate your Hugo deployments? [Sign up for DeployHQ](https://www.deployhq.com/signup) — it's free for one project.

Need help? Contact us at [support@deployhq.com](mailto:support@deployhq.com) or on [Twitter/X](https://x.com/deployhq).
