All Projects → spech66 → Hugo Best Practices

spech66 / Hugo Best Practices

Licence: mit
Best practices and ideas for Hugo the open-source static site generator.

Programming Languages

shell
77523 projects

Projects that are alternatives of or similar to Hugo Best Practices

Hugo Primer
Hugo theme based on GitHub's Primer CSS
Stars: ✭ 103 (-32.68%)
Mutual labels:  hugo, hugo-theme, hugo-site
hugo-shortcodes-netlify-cms
Shortcodes of Hugo for Netlify CMS Text Editor
Stars: ✭ 50 (-67.32%)
Mutual labels:  hugo-theme, hugo, hugo-site
hugo-initio
Hugo Theme port of Initio bootstrap template by GetTemplate
Stars: ✭ 58 (-62.09%)
Mutual labels:  hugo-theme, hugo, hugo-site
hugo-sugoi
Hugo-Sugoi - An Ultra Minimal Hugo Theme based on Skeleton
Stars: ✭ 29 (-81.05%)
Mutual labels:  hugo-theme, hugo, hugo-site
Hugo Casper Two
Port of Casper 2.x to Hugo
Stars: ✭ 135 (-11.76%)
Mutual labels:  hugo, hugo-theme, hugo-site
geeky-hugo
Geeky is a Personal Hugo blog theme focused on high speed. Geeky is fully responsive, Superfast, and powered by Bootstrap v5.
Stars: ✭ 44 (-71.24%)
Mutual labels:  hugo-theme, hugo, hugo-site
bookworm-light
Bookworm is a clean and modern Hugo blog theme focused on high speed and support multiple authors.
Stars: ✭ 59 (-61.44%)
Mutual labels:  hugo-theme, hugo, hugo-site
timer-hugo
Timer is a personal portfolio theme powered by Hugo. It also can be use as a landing page theme.
Stars: ✭ 123 (-19.61%)
Mutual labels:  hugo-theme, hugo, hugo-site
Hugo Theme Jane
A readable & concise theme for Hugo
Stars: ✭ 669 (+337.25%)
Mutual labels:  hugo, hugo-theme, hugo-site
Wowchemy Hugo Modules
🔥 Hugo website builder, Hugo themes & Hugo CMS. No code, build with widgets! 创建在线课程,学术简历或初创网站。
Stars: ✭ 6,093 (+3882.35%)
Mutual labels:  hugo, hugo-theme, hugo-site
influencer-hugo
Influencer is a Hugo theme for book authors and writers. It has also Snipcart supports for order books and payments.
Stars: ✭ 66 (-56.86%)
Mutual labels:  hugo-theme, hugo, hugo-site
Hugo Theme Learn
Porting Grav Learn theme to Hugo
Stars: ✭ 1,155 (+654.9%)
Mutual labels:  hugo, hugo-theme, hugo-site
inventory
UNICEF Open Source Inventory. A UNICEF Global Innovation knowledge base of best practices and resources for working and leading Open.
Stars: ✭ 23 (-84.97%)
Mutual labels:  hugo, best-practices, hugo-site
hugo-identity-theme
Little profile/card-style template for Hugo. Based on Identity by HTML5 UP.
Stars: ✭ 87 (-43.14%)
Mutual labels:  hugo-theme, hugo, hugo-site
navigator-hugo
Navigator Business theme powered by Hugo. It also could be used for a personal portfolio.
Stars: ✭ 133 (-13.07%)
Mutual labels:  hugo-theme, hugo, hugo-site
hugo-tufte
Content centric Hugo blogging theme styled with Tufte-Css
Stars: ✭ 58 (-62.09%)
Mutual labels:  hugo-theme, hugo, hugo-site
persian-hugo
Persian is a box design personal blog theme based on Bootstrap and powered by Hugo. It is very responsive and perfectly fits on any sized screen device.
Stars: ✭ 32 (-79.08%)
Mutual labels:  hugo-theme, hugo, hugo-site
tomanistor.com
Personal portfolio website and blog created with Hugo
Stars: ✭ 14 (-90.85%)
Mutual labels:  hugo-theme, hugo, hugo-site
Hugo Awesome Identity
😤 Awesome Identity is a single-page Hugo theme to introduce yourself.
Stars: ✭ 301 (+96.73%)
Mutual labels:  hugo, hugo-theme, hugo-site
Phugo
Phugo [ˈfjuːgəʊ] is a gallery/photoblog theme for Hugo.
Stars: ✭ 51 (-66.67%)
Mutual labels:  hugo, hugo-theme, hugo-site

Hugo - Best practices

Best practices and ideas for Hugo the open-source static site generator.

Themes based on this best practices: Bootstrap-BP, Materialize-BP, Bootstrap-BP hugo startpage.

Table of contents

Content organization

Keep all images next to the index Markdown file. This allows to keep the images in the highest possible resolution and let hugo resize them to the perfect size for the current theme (see Images below).

├── mysite/
    ├── content/
    │   └── posts/
    │       ├── 0001-firstpost/
    │       │   ├── index.md
    │       │   └── me.jpg
    │       ├── 0002-secondpost/
    │       │   ├── index.md
    │           └── fun.jpg
    ├── about/
    │   └── index.md

There is a Discussion on this in the Forum.

Git repository and CI Tools

Keep your site in a version control system like Git. This provides backup, history and multi user editing out of the box.

Use Continuous Integration/Deployment to publish your website after git push. Simple solutions like webhook might do the job. For complex scenarios you might want to use something like Jenkins. For most cases Jenkins will be overkill.

You can sync files using rsync after a successfull build. Have a look at the provided deployment scripts in this repository.

Content types and archetypes

Define your required types. A blog usually goes with pages and posts. Pages won't have fields like the author or creation dates displayed. Pages are usually reached under their name directly. Posts will be posted serveral times a month and might have a structure like /year/month/name. The archetypes should reflect the data that is needed for the content. Posts should have tags and categories applied.

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

This might be the archetype for posts. I prefect to collect all categories and tags in the archetype so I can remove all unused ones for the new blog post.

---
title: "{{ replace .Name "-" " " | title }}"
author: Sebastian
type: post
date:  {{ now.Format "2006-01-02" }}
featured_image: myimage.jpg
draft: true
categories:
  - A
  - B
  - C
tags:
  - Hugo
  - Game Development
  - Internet of Things (IoT)
  - Linux
  - ...
description: xxx
---

CONTENT

 

Source: xyz

Configure the site

Configure your new site with all relevant options. These are helpful values to start with.

# Settings
baseURL = "https://www.spech.de/"
languageCode = "de-DE" # or en-US
title = "My hugo page"
description = "Nice page"
# theme = "hugo-future-imperfect" # <- you won't need this as we copy the theme data!
googleAnalytics = "UA-111111111111-1"
canonifyURLs = true
copyright = "Sebastian Pech"
enableRobotsTXT = true

[sitemap]
    changefreq = "weekly"
    priority = 0.5

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

Make sure to send your sitemap.xml file to Google Search Console, Bing Webmaster Tools, ...

CSS and JavaScript

Old themes kept the css and js files in the static folder. Sometimes tools like Gulp, Grunt and Webpack were used for pre-processing. The latest version of Hugo will do all the stuff like bundling and minifiy for you. For this to work the files have to be put in the assets folder.

There are three critical methods to use as the bare minimum minify, fingerprint and slice. SCSS might make use of toCSS and postCSS.

With minify you will get a minified version of your files. (Hugo Documentation)

The fingerprint adds a unique string to the name so that the browser won't cache your files on modification. (Hugo Documentation)

Finally slice allows you to concat multiple files to a new one. This works best with minify. (Hugo Documentation)

CSS

Putting the above methods in place the minified main.css will be created as described below. Keep in mind that the files has to be in the assets folder.

{{ $stylemain := resources.Get "css/main.css" | minify | fingerprint "sha512" }}
<link rel="stylesheet" href="{{ $stylemain.RelPermalink }}" integrity="{{ $stylemain.Data.Integrity }}">

For processing SCSS Hugo provides two functions. (Hugo Documentation)

{{ $stylemain := resources.Get "scss/main.scss" | toCSS | postCSS (dict "use" "autoprefixer") | minify | fingerprint "sha512" }}
<link rel="stylesheet" href="{{ $stylemain.RelPermalink }}" integrity="{{ $stylemain.Data.Integrity }}">

Combining all css files to one minified file allows fewer HTTP requests. This is done using slice.

{{ $cssbootstrap := resources.Get "/css/bootstrap.css" }}
{{ $cssmain := resources.Get "/css/main.css" }}
{{ $csscustom := resources.Get "/css/custom.css" }}
{{ $allcss := slice $cssbootstrap $cssmain $csscustom | resources.Concat "/css/vendor.css" | minify | fingerprint "sha512" }}
<link rel="stylesheet" href="{{ $allcss.RelPermalink }}" integrity="{{ $allcss.Data.Integrity }}">

Javascript

Usually a theme will contain multiple JS files which might require a specific order. This is where slice comes into handy.

{{ $jquery := resources.Get "/js/jquery-v6.6.6/jquery.min.js" }}
{{ $bootstrap := resources.Get "/js/bootstrap-v4.6.0/bootstrap.min.js" }}
{{ $main := resources.Get "/js/main.js" }}

{{ $fullscript := slice $jquery $bootstrap $main | resources.Concat "/js/vendor.js" | minify | fingerprint "sha512" }}
<script src="{{ $fullscript.RelPermalink }}" integrity="{{ $fullscript.Data.Integrity }}"></script>

Conditionals

All scripts and styles that are needed only on specific pages should be wrapped in conditionals.

{{ if .Params.customPageColor }}
    <style>
        body { background-color: red; }
    </style>
{{ end }}
{{ if .Params.contactScript }}
    <script src="/js/my-contact-script.js"></script>
{{ end }}

Images

Image files should never be larger than necessary.

Hugo allows you to create resources from .Params information (Hugo Documentation). The resources can be processed with the image processing functions from Hugo afterwards (Hugo Documentation). This allows you to keep the original images next to the Markdown files (as mentioned before) and let Hugo generate thumbnails and smaller versions.

featured_image: my-blog-header-1.jpg

This example resizes the image mentioned in the featured_image parameter of the blog page to a version with 800 pixel width.

{{ if .Params.featured_image }}
    {{ $siteurl := (.RelPermalink) }}
    {{ $sitetitle := (.Title) }}
    {{ with .Resources.GetMatch (.Params.featured_image) }}
        {{ $thumb := .Resize "800x" }}
        <img src="{{ $thumb.Permalink }}" alt="{{ $sitetitle }}">
    {{ end }}
{{ end }}

Caching and .htaccess

See the example .htaccess in the static folder. It covers the following points.

  • Redirects for old content
  • Compression
  • Caching
  • SSL
  • HSTS and Content Security Policies
  • Errror documents
  • Wordpress migration rules

Make sure you understand every rule before applying it! The Content-Security-Policy might break your page if you rely on external sources.

Add a Schema.org partial

UPDATE: Even better use Hugo internal templates for this.

UPDATE (Hugo >= 0.60.0): According to the patch notes Hugo processes the images in a new order. The image logic in the 3 SEO internal templates twitter_cards.html, opengraph.html, and schema.html is consolidated: images page param first, then bundled image matching *feature*, *cover* or *thumbnail*, then finally images site param.

Add a Schema.org partial according to .

# layouts/partials/header.html
...
{{ partial "seo_schema" . }}
<title>
...
// layouts/partials/seo_schema.html
<script type="application/ld+json">
{
    "@context" : "http://schema.org",
    "@type" : "BlogPosting",
    "mainEntityOfPage": {
         "@type": "WebPage",
         "@id": "{{ .Site.BaseURL }}"
    },
    "articleSection" : "{{ .Section }}",
    "name" : "{{ .Title }}",
    "headline" : "{{ .Title }}",
    // "description" : "{{ if .Description }}{{ .Description }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ end }}{{ end }}",
    "description" : "{{ with .Description }}{{ . }}{{ else }}{{ .Site.Params.description }}{{ end }}"
    "inLanguage" : "{{ .Lang }}",
    "author" : "{{ range .Site.Author }}{{ . }}{{ end }}",
    "creator" : "{{ range .Site.Author }}{{ . }}{{ end }}",
    "publisher": "{{ range .Site.Author }}{{ . }}{{ end }}",
    "accountablePerson" : "{{ range .Site.Author }}{{ . }}{{ end }}",
    "copyrightHolder" : "{{ range .Site.Author }}{{ . }}{{ end }}",
    "copyrightYear" : "{{ .Date.Format "2006" }}",
    "datePublished": "{{ .Date | safeHTML }}",
    "dateModified" : "{{ .Date | safeHTML }}",
    "url" : "{{ .Permalink }}",
    "wordCount" : "{{ .WordCount }}",
    "keywords" : [ {{ if isset .Params "tags" }}{{ range .Params.tags }}"{{ . }}",{{ end }}{{ end }}"Blog" ]
}
</script>

I modified the example with {{ .Date | safeHTML }} otherwise Hugo replaces the + for positive timezones (like GTM, MEZ, ...) with a HTML escaped sequence which makes the javascript illegal for HTML check tools.

Setting .Site.Author is a bit tricky. Use this snippet.

[Author]  
  name = "Sebastian Pech"

External links in new window

Starting with Hugo 0.60 and the Goldmark parser external links won't open in a new window. The hrefTargetBlank from Blackfriday is not supported in Goldmark. In the hugo-shortcodes collection the render-link.html shortcode will fix the problem. Put the file in \layouts\_default\_markup and alls urls starting with http(s) will get the target="_blank" rel="noopener noreferrer" properties.

Front-End Checklist

Walk trough every point in the Front-End Checklist and the Front-End Performance Checklist.

Awesome Hugo list

Additional links and resources can be found at Awesome Hugo. A curated list of awesome things related to Hugo.

Tools

There are some tools and websites that can validate your page and check the speed.

  • webhint is a linting tool that will help you with your site's accessibility, speed, security and more, by checking your code for best practices and common errors.
  • Varvy SEO tool See how well a page follows the Google guidelines.
  • Google Structured Data Testing Tool Helps validating the structured data on the website.
  • Google PageSpeed Insights checks performance, loading times and image sizes.
  • Google Lighthouse performs audits on website performance, best practices, accessibility and SEO.
  • SSL Server Test is a free online service performing a deep analysis of the configuration of any SSL web server on the public Internet.
  • Mozilla SSL Configuration Generator An easy-to-use secure configuration generator for web, database, and mail software.
  • SEORCH German SEO testing tool.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].