Introduction to Hugo

+

Hugo title

What is Hugo?

Simply put, Hugo generates websites. More specifically, it generates static HTML, CSS, and JavaScript files from your content and themes. Your content is specified in Markdown and YAML/TOML text format and there are hundreds of design themes available at themes.gohugo.io, most of which are freely available under the MIT License.

Installing Hugo

You can install Hugo very easily via a terminal command on your operating system:

  • Windows Terminal (Admin): winget install Hugo.Hugo.Extended
  • macOS Terminal: brew install hugo
  • Linux Terminal: apt install hugo (Debian-based), or dnf install hugo (Red Hat-based)

Creating a Personal Portfolio Site Using Hugo

Working with Hugo is relatively easy using commands and a text editor – while the commands I use throughout this post are for Linux/macOS and the vi text editor, you can easily modify them for Windows (dir instead of ls) and any other text editor of your choice (e.g., code instead of vi for Visual Studio Code).

1. Set up a new Hugo site:

  • mkdir Hugo && cd Hugo
  • hugo new site mysite --format="yaml" (YAML is a cleaner text configuration format than the default of TOML)
  • cd mysite

2. Download a Hugo theme to the mysite/themes subfolder (we’ll use the Hugo-Profile theme):

  • cd themes
  • git clone https://github.com/gurusabarish/hugo-profile
  • cd .. && ls and note the mysite directory structure
    • content – stores website content (e.g., blogs) in Markdown and is empty by default
    • static – contains files that will be added to the website when it is generated)
    • public – contains the generated website, including all HTML, CSS, and JavaScript files (not shown until you generate your website)
    • Other folders are listed in Hugo’s documentation

3. Copy the example site content from the theme, compile the website and run it in a local Hugo web server that listens on port 1313:

  • cp -R themes/hugo-profile/exampleSite/content/* content
  • cp -R themes/hugo-profile/exampleSite/static/* static
  • cp themes/hugo-profile/exampleSite/hugo.yaml .
  • hugo server –D (keep Terminal open)

Now, open a web browser and navigate to localhost:1313 to see your site (you can click the moon icon to switch to dark mode):

Sample Hugo Site

Note that this is a very complex example – we would normally reduce features to create a portfolio site that suits our needs. If you drag your window size larger and smaller you’ll see how the website changes – this is called responsive web design and is largely performed by CSS.

To stop running the website, you can return to the shell running hugo server –D and press Ctrl+C, but it’s better to keep it open while editing it –- when you change the content (Markdown, YAML/TOML), Hugo recompiles it and updates the web server so you can see your changes immediately.

4. Modify core site content:

In a new shell, run vi hugo.yaml and peruse the content. Following are some changes you can start with as you’re getting used to this Hugo template (make sure you view the results in your web browser after each edit):

  • Change title: "Yourname Profile" (the title shown in the web browser tab)
  • Comment out the entire –identifier: gallery paragraph (including its indented tags)
  • Under params: change the title and description
  • Under navbar: change the brandName and disable the Experience, Education, and Achievements sections (change false to true) since these would instead be listed on your LinkedIn
  • Under hero: and about:, change the text values to suit your needs (we’ll replace the images/icons later)
  • The experience:, education:, and achievements: sections can be disabled (change enable:true to enable:false) if you disabled in the top menu earlier
  • Under contact: update the text values to your contact information and message
  • Under footer: note that the 3 most recent blog posts are shown from the blogs section (later), and then update your social media links to the actual profile URLs for each social media website, commenting any you don’t use

5. Modify graphics and style:

Go to mysite/static and note the fav.png file and contents of the images subfolder:

  • Fav.png is a Favicon (icon displayed next to your site name and in the browser tab)
    • Download another one from the Internet to replace it (or create your own up to 32x32 pixels) -– you can download Favicons from icons8.com (choose favicon as the download format)
    • Remove (or rename) fav.png, add your new fav.png file to the folder
    • This fav.png file is referenced under the params: section of your hugo.yaml (look for the line!)
  • The main person picture on the site is mysite/static/images/hero.svg
    • SVG graphic files are common on websites, but you can choose any other format (e.g., jpg, png)
    • Generate a profile pic for yourself (e.g., using AI) or use a real picture that is cropped square and add the file to the images folder
    • Next, in the hero: section of hugo.yaml, update the line image: /images/hero.svg to instead point to your new filename (e.g., image: /images/jason.jpg)
  • Repeat this same process to replace the image in your About Me section
    • The default image is mysite/static/images/me.png – replace it with a different image or fun graphic from the web (or use a real pic here and a different image or fun graphic to replace hero.svg)
    • Note the other pics here: mathjax.png, post.jpg, and achievement.jpg are used for the default blog posts, and the pics for each project are in the projects subfolder – if you wish to change these, ensure you also update the filename that references them in hugo.yaml or the associated blog post (discussed later)

This brings us to the importance of colour design. In general, start with key images that you like and work your portfolio around those colours (e.g., the colours on this site are taken from my main profile art). Check to make sure any graphics look good in light and dark mode (changing them if necessary) as well as choose clean fonts – the default ones in the Hugo-Profile theme are very common as they are clean and readable, but you can change their size and weight easily. Most visual design is under the params: section in hugo.yaml:

Hugo visual parameters

You can disable animations or force a specific theme (light/dark), as well as adjust font size/weight/alignment, or override the default colours for the light and dark themes. Font sizes are in relative units of measurement (relative to the root font on the webpage) –- most browsers set the root font size to 16 pixels, so 1rem = 16 pixels. Colours are shown in hexadecimal (e.g., #343a40 is grey) – you can choose other colours visually and obtain their hexadecimal codes from htmlcolorcodes.com or www.color-hex.com.

While we updated the social media links at the bottom of the webpage earlier, we didn’t update the Resume and key social media links you’ll want every viewer to see who visits your website. These links are near the top and called Call-to-Action (CTA) links because they stand out and encourage viewers to click on them. The CTA buttons are under the hero: section in hugo.yaml:

Call-to-Action links

If you add a resume.pdf file to mysite/static you can modify the url: "#" line to url: "/resume.pdf" to refer to it. Similarly, you can modify the icons from fontawesome.com and add the associated links. But you don’t need to read through that site – if you Google “fontawesome LinkedIn”, you’ll quickly get the name of the LinkedIn fontawesome icon. In general, your resume, GitHub, and LinkedIn are the most important CTAs (fewer CTAs are better).

6. Create blog posts

Blog posts are written in Markdown and stored in .md files in the mysite/content/blogs directory. You can remove .md files to remove blog posts, or add new ones (e.g., by copying and editing an existing one and updating the title/date). The 5 sample blog posts tell you how to use different Hugo and Markdown features. If you’re new to Markdown format, explore the blog post called markdown-syntax.md (comparing the contents to the actual composited blog post on your Hugo web server).

I recommend copying the markdown-syntax.md file and renaming it to create new blog posts, deleting any elements within that you don’t need. Here are some key tips:

  • Blog posts can be short or long depending on purpose
  • Longer blogs should have titles and subtitles with a larger font (e.g., H1/# is larger than H2/##)
  • Include at least 1 pic (the image: at the top, which is stored in mysite/static/images)
  • Hyperlinks use the syntax [name](URL) and URL can be local too (e.g., [Resume](/resume.pdf))
  • Use bullets for lists of key points or items
  • If the date on your blog post is in the future, make sure you use hugo server -DF instead of hugo server -D
  • Always remember Picasso’s advice:

Picasso Quote

Hosting your Website

Once you have a fully-functional portfolio website hosted locally with the built-in Hugo web server, we can copy it to a public web server. You could purchase a domain name and hosting from a hosting provider and upload the contents of the public folder to that provider, or use the free web hosting provided by GitHub (called GitHub Pages) like I do for my site and which I’ll discuss here.

First, create a free account on GitHub.com. This will require a valid email account, as well as the setup of 2FA (use the Microsoft Authenticator app). You will also need to choose a GitHub username –- this username will be used for your personal website (githubusername.github.io)

Next, update the baseURL on the first line of mysite/hugo.yaml to reflect the hosting location: baseURL:"https://githubusername.github.io/" (supply your GitHub username). Following this, you’ll need to recomposite your website to the public folder with the new baseURL:

  • cd mysite
  • hugo (or hugo -F if you have blog posts with a future date on them)

Return to GitHub.com, create a new repository (+ symbol), call it githubusername.github.io, choosing Public visibility and the option to initialize the repository with a README. In your repository, choose Settings, then select Pages from the left pane. Under Source, choose Deploy from a branch and ensure that the main branch is shown for the root (/).

Now, click your repository name in the upper left to return to your repository and click Add file > Upload files. Select all files in your mysite/public folder, drag them to the window, and click Commit changes. After a few moments, visit https://githubusername.github.io in your web browser to see your hosted site!

Each time you publish a new blog post or make changes, you can repeat this process, or leverage a GitHub syncing app like GitHub Desktop to do the same. If you want to add a comments section to your blog using the built-in GitHub Discussions feature, read my earlier blog post.