Hugo

Setting Up a Hugo Site from Scratch

Hugo is fast to build and fast to get started with, but a blank new site has some deliberate setup work before it is ready to publish. This walkthrough covers the full process from installation through your first deployed post.

Installing Hugo

Hugo distributes as a single binary — no runtime dependencies, no package manager required after the initial install.

macOS:

brew install hugo

Linux (Debian/Ubuntu):

sudo apt install hugo

Or download the latest binary directly from the Hugo releases page and add it to your PATH. Hugo ships in two versions: standard and extended. The extended version supports Sass/SCSS compilation and is required by some themes. When in doubt, install extended.

Verify the installation:

hugo version

Creating a New Site

hugo new site my-publication
cd my-publication

Hugo creates a directory structure:

my-publication/
├── archetypes/     # Content templates
├── assets/         # Files processed by Hugo Pipes (JS, CSS, images)
├── content/        # Your Markdown posts and pages
├── data/           # Data files (JSON, TOML, YAML)
├── layouts/        # HTML templates
├── static/         # Files copied verbatim to the output
├── themes/         # Installed themes
└── hugo.toml       # Site configuration

Installing a Theme

A fresh Hugo site has no templates, so it will not render anything useful without a theme (or your own layouts). Initialize a Git repository first:

git init

Then add a theme as a Git submodule. PaperMod is a clean, fast, widely used theme:

git submodule add https://github.com/adityatelange/hugo-PaperMod themes/PaperMod

Configure the theme and basic site settings in hugo.toml:

baseURL = "https://yoursite.com"
languageCode = "en-us"
title = "Your Publication"
theme = "PaperMod"

[params]
  description = "A publishing site"
  ShowReadingTime = true
  ShowShareButtons = false
  ShowPostNavLinks = true
  ShowBreadCrumbs = true

[menu]
  [[menu.main]]
    identifier = "about"
    name = "About"
    url = "/about/"
    weight = 10
  [[menu.main]]
    identifier = "archive"
    name = "Archive"
    url = "/archives/"
    weight = 20

By default, Hugo generates URLs like /posts/my-post-title/. You can customize this:

[permalinks]
  posts = "/:year/:month/:slug/"

Set your permalink structure before publishing. Changing it later requires redirects.

Writing Your First Post

Hugo’s new command creates content from archetypes (templates):

hugo new posts/my-first-post.md

This creates content/posts/my-first-post.md pre-populated from the default archetype:

---
title: "My First Post"
date: 2026-04-29T10:00:00+00:00
draft: true
---

Change draft: true to draft: false when you are ready to publish. Add tags and any other frontmatter your theme uses:

---
title: "My First Post"
date: 2026-04-29
draft: false
tags: ["publishing", "getting started"]
featured_image: ""
---

Post content in Markdown goes here.

Customizing Your Archetype

Archetypes live in archetypes/. Edit archetypes/default.md to set default frontmatter for all new content:

---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: false
tags: []
featured_image: ""
---

Now every hugo new command generates content with your standard fields.

Running the Development Server

hugo server

Hugo starts a local server at http://localhost:1313 with live reload. Edit a file and the browser updates immediately. To include draft posts in the preview:

hugo server -D

Setting Up Taxonomies

Hugo has built-in support for tags and categories. Additional taxonomies are defined in hugo.toml:

[taxonomies]
  tag = "tags"
  category = "categories"
  series = "series"
  author = "authors"

Each taxonomy automatically gets archive pages — /tags/, /categories/, etc. — listing all content under that classification.

Building for Production

hugo

Hugo builds the full site into the public/ directory. Build time for a site with several hundred posts is typically under a second.

Deployment

The public/ directory is a complete static site. Deploy it anywhere that serves static files.

Netlify — connect your Git repository and add a netlify.toml:

[build]
  command = "hugo"
  publish = "public"

[build.environment]
  HUGO_VERSION = "0.145.0"
  HUGO_ENV = "production"

Push to your repository and Netlify builds and deploys automatically on every commit.

Cloudflare Pages — similar to Netlify. Set the build command to hugo and the output directory to public.

GitHub Pages — use the official Hugo GitHub Action to build and deploy on push.

Next Steps

With a working site and your first post published, the natural next steps are:

  • Setting up search (Pagefind is the easiest path for Hugo)
  • Configuring an RSS feed (Hugo generates one automatically at /index.xml)
  • Adding an About page (hugo new about.md in content/)
  • Customizing your theme’s layout files in layouts/
  • Setting up analytics (Plausible or Fathom integrate cleanly with static sites)

Hugo’s documentation at gohugo.io is thorough and well-organized. Once the basics are in place, most questions are answered there.