What is Hugo Static Site Generator?
Hugo is a lightning-fast static site generator written in Go. It takes plain text files (usually Markdown with YAML/TOML front matter) and a set of HTML templates to produce a complete, ready-to-deploy website. There is no database, no server-side processing at runtime, and no dynamic content generation—every page is pre-built as a static HTML file. This makes Hugo sites incredibly fast, secure, and easy to host on services like GitHub Pages, Netlify, or any simple web server.
Hugo’s strengths include blazing build speeds (a medium-sized site builds in milliseconds), flexible content organization, a powerful templating language, and a rich ecosystem of pre-made themes. For developers, designers, and writers building a personal portfolio, Hugo offers the perfect balance between simplicity and control.
Why Hugo for Your Portfolio Website?
🚀 Deploy your AI agent in 10 minutes
Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.
Try it free →A portfolio site needs to load quickly, showcase your work effectively, and be easy to update. Hugo delivers on all fronts:
- Speed & Performance: Static files serve instantly. No database queries, no server-side rendering delays. Combined with a CDN, your portfolio will feel snappy everywhere.
- Developer-Friendly Markdown: Write project descriptions, blog posts, and case studies in Markdown with front matter for metadata. You stay focused on content, not formatting.
- Complete Theming: Hundreds of free, responsive portfolio themes are available. You can also build a custom theme using Hugo’s templating (Go’s
html/template), giving full design control. - Easy Deployment: Push a Hugo site to GitHub, connect it to Netlify or Vercel, and get continuous deployment with free SSL in minutes. No server maintenance.
- Markdown & Shortcodes: Embed images, code snippets, videos, or interactive elements with Hugo’s shortcodes without breaking the writing flow.
Whether you’re a front-end developer, designer, or data scientist, a Hugo-powered portfolio gives you a clean, fast, and professional online presence with minimal overhead.
Setting Up Hugo
Before creating your portfolio, install Hugo on your development machine. Hugo runs on macOS, Linux, and Windows.
macOS (Homebrew)
brew install hugo
Linux (apt or snap)
sudo apt update
sudo apt install hugo # Debian/Ubuntu
# or using snap
sudo snap install hugo
Windows (Chocolatey or Scoop)
choco install hugo -y # Chocolatey
# or
scoop install hugo # Scoop
Verify the installation:
hugo version
You also need a text editor (VS Code, Sublime, etc.) and Git for version control. A basic understanding of the terminal/command line is helpful.
Creating a New Hugo Portfolio Site
Hugo’s CLI makes scaffolding trivial. Navigate to your projects folder and run:
hugo new site my-portfolio
cd my-portfolio
This creates the basic directory structure without a theme. Right now, the site has no visual appearance. Next, we’ll add a theme specifically suited for portfolios.
Choosing and Installing a Theme
Hugo themes are available on themes.gohugo.io. For a portfolio, look for themes tagged “portfolio” or “personal.” Popular choices include hugo-coder, hugo-creative-portfolio-theme, hugo-devfolio, and hugo-tranquilpeak. In this tutorial, we’ll use a hypothetical theme called hugo-portfolio. Replace it with your chosen theme’s repository URL.
# Initialize git (themes are added as git submodules by convention)
git init
# Add the theme as a submodule
git submodule add https://github.com/someauthor/hugo-portfolio.git themes/hugo-portfolio
After adding the theme, you need to tell Hugo to use it. Open the site’s main configuration file (by default config.toml in the site root) and set the theme:
# config.toml (or config.yaml, config.json)
theme = "hugo-portfolio"
Now you can start the Hugo development server:
hugo server -D
The -D flag includes draft content. Open http://localhost:1313 in your browser. You’ll see a basic site with placeholder content provided by the theme.
Understanding Hugo Directory Structure
A typical Hugo site after adding a theme looks like this:
my-portfolio/
├── archetypes/
│ └── default.md
├── config.toml (or config.yaml)
├── content/
│ ├── _index.md (home page content)
│ ├── projects/
│ │ ├── _index.md (projects list page)
│ │ └── project1.md
│ ├── about/
│ │ └── index.md (or _index.md)
│ └── blog/
│ ├── _index.md
│ └── post1.md
├── data/
├── layouts/ (optional: override theme templates)
├── static/ (images, CSS, JS – copied as-is)
├── themes/
│ └── hugo-portfolio/ (the theme you installed)
└── .gitignore
Key directories for portfolio building:
config.toml: site-wide parameters like title, baseURL, theme, and custom variables.content/: all Markdown files that become pages. The folder hierarchy defines the URL structure.layouts/: custom template overrides (optional but powerful).static/: static assets like your resume PDF, images, favicon, or custom CSS.archetypes/: templates for new content files created withhugo new.
Configuring Your Site
The configuration file controls everything from the site title to social links. Here’s a sample config.toml for a portfolio using our imaginary theme:
baseURL = "https://yourusername.dev/"
languageCode = "en-us"
title = "Alex Rivera – Full‑Stack Developer"
theme = "hugo-portfolio"
[params]
# Homepage intro
author = "Alex Rivera"
tagline = "I build accessible, performant web applications."
avatar = "images/avatar.jpg"
email = "hello@alexrivera.dev"
github = "https://github.com/alexrivera"
linkedin = "https://linkedin.com/in/alexrivera"
# Menu configuration
[[menu.main]]
name = "Projects"
url = "/projects/"
weight = 1
[[menu.main]]
name = "About"
url = "/about/"
weight = 2
[[menu.main]]
name = "Blog"
url = "/blog/"
weight = 3
# Enable syntax highlighting for code blocks (if theme supports it)
pygmentsCodeFences = true
pygmentsStyle = "monokai"
Most portfolio themes expect certain front matter fields in your content files (like title, date, draft, and custom ones like featured_image). Read your theme’s documentation to see what’s available.
Adding Portfolio Content
Now the real work begins—creating pages that showcase your projects, skills, and background.
Homepage (_index.md)
The home page content usually lives in content/_index.md. This file controls the homepage copy, not the layout. For a portfolio, it might contain a hero message and a brief introduction:
---
title: "Home"
date: 2025-04-01T10:00:00+02:00
draft: false
---
# Hello, I'm Alex Rivera
I'm a full‑stack developer passionate about building tools that make people's lives easier. Here you'll find a selection of projects, articles, and my professional journey.
Take a look around, and if something sparks your interest, [get in touch](mailto:hello@alexrivera.dev).
The front matter (the YAML/TOML between ---) sets metadata. The Markdown body becomes the page content. The theme’s layout will wrap this in your chosen design.
Projects Section
For each project, create a Markdown file under content/projects/. A typical project page:
---
title: "Weather Dashboard"
date: 2025-03-20T18:00:00+02:00
draft: false
summary: "A real‑time weather dashboard with interactive maps and alerts."
tags: ["React", "D3.js", "OpenWeather API"]
featured_image: "images/weather-dashboard-thumb.jpg"
---
## Overview
The Weather Dashboard fetches live weather data from the OpenWeather API and visualizes it using D3.js maps and charts. Users can search any city, view 7‑day forecasts, and set custom alerts.
## Technical Highlights
- **React** front‑end with custom hooks for data fetching
- **D3.js** for dynamic map overlays and animated charts
- **Node.js** backend proxy to secure API keys
- **Service Worker** for offline support and caching
## Links
- [Live Demo](https://weather.example.com)
- [Source Code](https://github.com/alexrivera/weather-dashboard)
The theme may render the featured_image as a thumbnail on listing pages. Tags can be used for filtering (if the theme supports it). Keep project pages concise but informative.
About Page
Create content/about/index.md (or _index.md if the theme uses list pages for about sections). This is your personal bio, skills, and timeline.
---
title: "About Me"
date: 2025-04-05T14:30:00+02:00
draft: false
---
## Who am I?
I'm a software engineer based in Barcelona, currently working at TechCo. I specialize in front‑end architecture and accessibility. Outside work, I contribute to open‑source mapping tools and write about performance optimization.
## Skills
- **Languages:** JavaScript, TypeScript, Python, Go
- **Frameworks:** React, Next.js, Svelte, FastAPI
- **Tools:** Docker, Kubernetes, AWS, Terraform
## Experience
- **Senior Frontend Engineer @ TechCo** (2023–present)
- **Full‑stack Developer @ StartUp Inc** (2020–2023)
- **Junior Developer @ WebAgency** (2018–2020)
Blog (Optional)
A blog adds personality and demonstrates communication skills. Create posts under content/blog/. Hugo automatically orders them by date.
---
title: "How I Reduced Build Times by 60% with esbuild"
date: 2025-02-10T09:00:00+02:00
draft: false
tags: ["performance", "esbuild", "webpack"]
---
We recently migrated our React app from webpack to esbuild. Here's what we learned...
Customizing the Theme
A portfolio must reflect your personal brand. Hugo allows you to override any theme template without modifying the theme itself. This keeps theme updates easy via git.
Overriding Layouts and Partials
To customize the homepage layout, copy the theme’s layouts/index.html (or list.html for listing pages) into your site’s layouts/ directory, preserving the path structure. For example, to override the single project page template:
cp themes/hugo-portfolio/layouts/projects/single.html layouts/projects/single.html
Now edit layouts/projects/single.html. You can rearrange sections, add new classes, or insert custom partials.
Common customizations for a portfolio:
- Add a footer partial: Create
layouts/partials/footer.htmlwith your own copyright, social links, and maybe a "Back to top" link. - Custom 404 page: Override
layouts/404.htmlwith a friendly, branded error page. - Inject custom CSS: Place a
static/css/custom.cssfile and link it by overriding the header partial.
Adding Custom CSS
Most themes include a way to add extra styles. If not, override the head.html partial (often in layouts/partials/head.html) and add a link to your custom stylesheet:
<link rel="stylesheet" href="{{ "css/custom.css" | relURL }}">
Then place your CSS in static/css/custom.css. For example, adjust typography or add subtle animations:
/* static/css/custom.css */
body {
font-family: 'Inter', sans-serif;
}
.project-card {
transition: transform 0.2s ease;
}
.project-card:hover {
transform: translateY(-4px);
}
Using Shortcodes for Richer Content
Hugo shortcodes let you embed complex HTML or interactive elements without leaving Markdown. A typical portfolio might use a shortcode for a responsive image gallery or a code sandbox embed. If your theme lacks them, you can create your own. Create a file like layouts/shortcodes/codepen.html:
{{- with .Get "url" -}}
<iframe
src="{{ . }}"
width="100%"
height="400"
frameborder="0"
loading="lazy"
allowfullscreen></iframe>
{{- end -}}
Then in any Markdown file:
{{< codepen url="https://codepen.io/alex/pen/example" >}}
Deploying Your Portfolio
A static site needs a host that serves HTML files. Two popular, free options are GitHub Pages and Netlify. Both integrate seamlessly with Hugo.
GitHub Pages
Create a GitHub repository named <username>.github.io (for user pages) or any repo for project pages. Push your Hugo site source to a branch (often main or source). Then use GitHub Actions to build Hugo and deploy to the gh-pages branch. Many Hugo themes include a sample workflow.
Example workflow (.github/workflows/hugo.yml):
name: Deploy Hugo site to GitHub Pages
on:
push:
branches:
- main
jobs:
build-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true # fetch Hugo themes
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: 'latest'
- name: Build
run: hugo --minify
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
publish_branch: gh-pages
After the first push, your portfolio will be live at https://<username>.github.io (or your custom domain if configured).
Netlify
Netlify offers drag-and-drop simplicity. Connect your GitHub/GitLab repository, tell Netlify the build command is hugo --minify and the publish directory is public. Netlify automatically detects Hugo and adds the correct build environment. It also provides free SSL, a CDN, and automatic branch deploys for previews.
For a custom domain, set the baseURL in config.toml to your domain, and Netlify handles HTTPS. You can also add a netlify.toml for fine-grained control:
[build]
command = "hugo --gc --minify"
publish = "public"
[build.environment]
HUGO_VERSION = "0.120.0" # pin a version for consistency
Both services work excellently. Netlify’s form handling and serverless functions can also power contact forms, but a simple mailto link or a third-party service (Formspree) often suffices for a portfolio.
Best Practices for a Hugo Portfolio
To make your portfolio stand out and remain maintainable, follow these guidelines:
- Version control everything: Keep your Hugo source in a Git repository. Include the theme as a submodule (not a copy) so you can update it easily.
- Optimize assets: Compress images (use WebP, responsive sizes) and minify CSS/JS. Hugo’s
--minifyflag helps, but you can also use asset pipeline tools. - Use meaningful front matter: Add
summary,tags, andfeatured_imageconsistently. This improves theme rendering and SEO. - Keep content DRY: For recurring elements like a tech stack badge, create a shortcode or a data template instead of repeating HTML.
- Responsive design is a must: Choose a theme that is mobile-first or override CSS to ensure your portfolio looks great on phones. Test with browser DevTools.
- Add a 404 page: Customize the 404 template to keep lost visitors engaged, maybe with a funny message and links to main sections.
- SEO and meta tags: Hugo themes often support Open Graph and Twitter Cards. Fill in the
descriptionfront matter and a site-widedescriptionin the config. Add astatic/robots.txtif needed. - Performance check: Use Lighthouse or PageSpeed Insights. Aim for green scores (100 on performance, accessibility). Hugo’s static nature already gives you a head start.
- Contact & social proof: Include a clear call to action—email, LinkedIn, or a contact form. Display testimonials or client logos if possible.
- Keep it fresh: Regularly update projects and blog posts. An outdated portfolio sends the wrong signal. Hugo makes updates as simple as editing a Markdown file and pushing to Git.
Conclusion
Hugo turns the process of building a portfolio website into an enjoyable, code-focused experience. You write content in Markdown, control layout with simple templates, and deploy with a single push. The result is a blazing-fast, secure, and highly customizable site that you fully own. By choosing a good theme, adding your projects and story, and following best practices around optimization and maintainability, you’ll create a portfolio that not only showcases your work but also demonstrates your technical taste. Now open your terminal, run hugo new site, and start building.