Code Blocks


Syntax highlighting, line numbers, and the copy button

Beautiful Hugo supports two syntax highlighting engines: Hugo’s built-in Chroma (default) and client-side Highlight.js. This page demonstrates Chroma, which is fast and built when the page renders.

Required Config

Beautiful Hugo supports two syntax highlighting engines: Hugo’s built-in Chroma (default) and client-side Highlight.js. See Configuration — Syntax Highlighting for the required hugo.toml settings for each engine.

Fenced Code Blocks

Use triple backticks with a language identifier, like this:

```json
{
  "example": "code"
}
```
{
  "example": "code"
}
# python
def fibonacci(n):
    """Return the nth Fibonacci number."""
    if n <= 1:
        return n
    a, b = 0, 1
    for _ in range(2, n + 1):
        a, b = b, a + b
    return b
// go
package main

import "fmt"

func main() {
    ch := make(chan string)
    go func() { ch <- "hello" }()
    fmt.Println(<-ch)
}
// javascript
const greet = (name) => {
  console.log(`Hello, ${name}!`);
};

greet("World");
# toml
[Params]
  subtitle = "My Site"
  colorScheme = "auto"
  selfHosted = false

Line Numbers

Use Hugo’s highlight shortcode with linenos to add line numbers:

{{< highlight python "linenos=table" >}}
def quicksort(arr):
    ...
{{< /highlight >}}
1
2
3
4
5
6
7
8
def quicksort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quicksort(left) + middle + quicksort(right)

Inline line numbers:

{{< highlight go "linenos=inline" >}}
func reverse(s string) string {
    ...
{{< /highlight >}}
1func reverse(s string) string {
2    runes := []rune(s)
3    for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
4        runes[i], runes[j] = runes[j], runes[i]
5    }
6    return string(runes)
7}

Line Highlighting

Use hl_lines to emphasize specific lines:

{{< highlight python "linenos=table, hl_lines=3 4" >}}
def process(data):
    result = []
    for item in data:       # highlighted
        result.append(item)  # highlighted
    return result
{{< /highlight >}}
1
2
3
4
5
def process(data):
    result = []
    for item in data:       # highlighted
        result.append(item)  # highlighted
    return result

Copy Button

Every code block automatically gets a copy-to-clipboard button in the top-right corner. Hover over any code block on this page to see it. The button strips line numbers before copying.

Including External Files

The include-code shortcode reads a source file from your project and renders it with syntax highlighting. It respects the same Chroma/HLJS setting as fenced code blocks.

{{< include-code file="hugo.toml" >}}

With explicit language and line options (Chroma only):

{{< include-code file="hugo.toml" language="toml" linenos="table" hl_lines="3-5" >}}

Live example

This page includes the example site’s own hugo.toml:

# This gets overridden when building for production
baseurl = "http://localhost:1313/"
DefaultContentLanguage = "en"
title = "Beautiful Hugo"
enableGitInfo = true

[[module.imports]]
   path = "github.com/halogenica/beautifulhugo"

[pagination]
  pagerSize = 5

[Services]
  [Services.Disqus]
    # Shortname = "XXX"
  [Services.googleAnalytics]
    # id = "XXX"

[taxonomies]
  category = "categories"
  tag = "tags"

[Params]
  subtitle = "Build a beautiful and simple website in minutes"
  mainSections = ["post", "recipe"]
  logo = "/img/avatar-icon.png" # Expecting square dimensions
  favicon = "/img/favicon.ico"
  dateFormat = ":date_long"
  commit = false
  rss = true
  readingTime = true
  wordCount = true
  colorScheme = "auto"
  # mathEngine = "katex"  # "katex" (default), "mathjax" (CDN only), or "none"
  socialShare = true
  delayDisqus = true
  showRelatedPosts = true
  disableFigureOverride = true
  headerImgStyle = "narrow"
  showSource = true
  sourceRepo = "https://github.com/halogenica/beautifulhugo/blob/master/exampleSite/"
  comment = "https://github.com/halogenica/beautifulhugo/commit/"

  [Params.search]
    provider = "fuse"

[[Params.bigimg]]
  src = "/img/triangle.jpg"
  desc = "Triangle"
[[Params.bigimg]]
  src = "/img/sphere.jpg"
  desc = "Sphere"
  position = "center top"
[[Params.bigimg]]
  src = "/img/hexagon.jpg"
  desc = "Hexagon"

#[Params.AISearchSummary.Googlebot]
#summaryLimit = 150
#[Params.AISearchSummary.robots]
#summaryLimit = 300


[Params.author]
  name = "Some Person"
  website = "yourwebsite.com"
  email = "youremail@domain.com"
  github = "username"
  twitter = "username"
  linkedin = "in/username" # company/username

[markup.highlight]
  noClasses = false

[markup.goldmark.parser.attribute]
  block = true

[markup.goldmark.renderer]
  unsafe = true

[[menu.main]]
    identifier = "setup"
    name = "Setup"
    weight = 1

[[menu.main]]
    parent = "setup"
    name = "Configuration"
    url = "page/configuration/"
    weight = 1

[[menu.main]]
    parent = "setup"
    name = "Pages & Layouts"
    url = "page/pages-and-layouts/"
    weight = 2

[[menu.main]]
    parent = "setup"
    name = "Theming"
    url = "page/theming/"
    weight = 3

[[menu.main]]
    parent = "setup"
    name = "SEO & i18n"
    url = "page/seo-and-i18n/"
    weight = 4

[[menu.main]]
    parent = "setup"
    name = "Comments & Social"
    url = "page/comments-and-social/"
    weight = 5

[[menu.main]]
    identifier = "features"
    name = "Features"
    weight = 2

[[menu.main]]
    parent = "features"
    name = "Shortcodes"
    url = "page/shortcodes/"
    weight = 1

[[menu.main]]
    parent = "features"
    name = "Code Blocks"
    url = "page/code-blocks/"
    weight = 2

[[menu.main]]
    parent = "features"
    name = "Markdown Extensions"
    url = "page/markdown-extensions/"
    weight = 3

[[menu.main]]
    parent = "features"
    name = "Figures & Galleries"
    url = "page/figures-and-galleries/"
    weight = 4

[[menu.main]]
    parent = "features"
    name = "Math & Diagrams"
    url = "page/math-and-diagrams/"
    weight = 5

[[menu.main]]
    identifier = "blog"
    name = "Blog"
    weight = 3

[[menu.main]]
    parent = "blog"
    name = "Posts"
    url = "post/"
    weight = 1

[[menu.main]]
    parent = "blog"
    name = "Tags"
    url = "tags/"
    weight = 2

[[menu.main]]
    parent = "blog"
    name = "Categories"
    url = "categories/"
    weight = 3

[[menu.main]]
    parent = "blog"
    name = "Archives"
    url = "archives/"
    weight = 4

[[menu.main]]
    name = "About"
    url = "page/about/"
    weight = 4

[outputs]
home = ["HTML", "RSS", "JSON"]
section = ["HTML", "RSS", "JSON"]
page = ["HTML"]

With line numbers and highlighted lines:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# This gets overridden when building for production
baseurl = "http://localhost:1313/"
DefaultContentLanguage = "en"
title = "Beautiful Hugo"
enableGitInfo = true

[[module.imports]]
   path = "github.com/halogenica/beautifulhugo"

[pagination]
  pagerSize = 5

[Services]
  [Services.Disqus]
    # Shortname = "XXX"
  [Services.googleAnalytics]
    # id = "XXX"

[taxonomies]
  category = "categories"
  tag = "tags"

[Params]
  subtitle = "Build a beautiful and simple website in minutes"
  mainSections = ["post", "recipe"]
  logo = "/img/avatar-icon.png" # Expecting square dimensions
  favicon = "/img/favicon.ico"
  dateFormat = ":date_long"
  commit = false
  rss = true
  readingTime = true
  wordCount = true
  colorScheme = "auto"
  # mathEngine = "katex"  # "katex" (default), "mathjax" (CDN only), or "none"
  socialShare = true
  delayDisqus = true
  showRelatedPosts = true
  disableFigureOverride = true
  headerImgStyle = "narrow"
  showSource = true
  sourceRepo = "https://github.com/halogenica/beautifulhugo/blob/master/exampleSite/"
  comment = "https://github.com/halogenica/beautifulhugo/commit/"

  [Params.search]
    provider = "fuse"

[[Params.bigimg]]
  src = "/img/triangle.jpg"
  desc = "Triangle"
[[Params.bigimg]]
  src = "/img/sphere.jpg"
  desc = "Sphere"
  position = "center top"
[[Params.bigimg]]
  src = "/img/hexagon.jpg"
  desc = "Hexagon"

#[Params.AISearchSummary.Googlebot]
#summaryLimit = 150
#[Params.AISearchSummary.robots]
#summaryLimit = 300


[Params.author]
  name = "Some Person"
  website = "yourwebsite.com"
  email = "youremail@domain.com"
  github = "username"
  twitter = "username"
  linkedin = "in/username" # company/username

[markup.highlight]
  noClasses = false

[markup.goldmark.parser.attribute]
  block = true

[markup.goldmark.renderer]
  unsafe = true

[[menu.main]]
    identifier = "setup"
    name = "Setup"
    weight = 1

[[menu.main]]
    parent = "setup"
    name = "Configuration"
    url = "page/configuration/"
    weight = 1

[[menu.main]]
    parent = "setup"
    name = "Pages & Layouts"
    url = "page/pages-and-layouts/"
    weight = 2

[[menu.main]]
    parent = "setup"
    name = "Theming"
    url = "page/theming/"
    weight = 3

[[menu.main]]
    parent = "setup"
    name = "SEO & i18n"
    url = "page/seo-and-i18n/"
    weight = 4

[[menu.main]]
    parent = "setup"
    name = "Comments & Social"
    url = "page/comments-and-social/"
    weight = 5

[[menu.main]]
    identifier = "features"
    name = "Features"
    weight = 2

[[menu.main]]
    parent = "features"
    name = "Shortcodes"
    url = "page/shortcodes/"
    weight = 1

[[menu.main]]
    parent = "features"
    name = "Code Blocks"
    url = "page/code-blocks/"
    weight = 2

[[menu.main]]
    parent = "features"
    name = "Markdown Extensions"
    url = "page/markdown-extensions/"
    weight = 3

[[menu.main]]
    parent = "features"
    name = "Figures & Galleries"
    url = "page/figures-and-galleries/"
    weight = 4

[[menu.main]]
    parent = "features"
    name = "Math & Diagrams"
    url = "page/math-and-diagrams/"
    weight = 5

[[menu.main]]
    identifier = "blog"
    name = "Blog"
    weight = 3

[[menu.main]]
    parent = "blog"
    name = "Posts"
    url = "post/"
    weight = 1

[[menu.main]]
    parent = "blog"
    name = "Tags"
    url = "tags/"
    weight = 2

[[menu.main]]
    parent = "blog"
    name = "Categories"
    url = "categories/"
    weight = 3

[[menu.main]]
    parent = "blog"
    name = "Archives"
    url = "archives/"
    weight = 4

[[menu.main]]
    name = "About"
    url = "page/about/"
    weight = 4

[outputs]
home = ["HTML", "RSS", "JSON"]
section = ["HTML", "RSS", "JSON"]
page = ["HTML"]

The file path is relative to the Hugo project root. If language is omitted, it is auto-detected from the file extension. See Configuration for the full parameter reference.

Inline Code

Use backticks for inline code: hugo serve -D or console.log("hello").