I wanted to update how my posts are looking on mastodon. I did not like that it only shows title and some default icon. I wanted to show image there, or some “kind of logo” of my website.
For illustration:

This is how my posts are looks now (… at least to the time when I published this article).
Version 1
I found how to generate simple square image - a logo of the page.

This looks so much better now and it is really easy to do. I just changed my opengraph.html file by adding following lines.
1{{ $img := resources.Get "img/og.png" }}
2{{- $img = $img.Resize "1200x" -}}
3{{- with $img.Process "webp q80" -}}
4 {{- $src := .Permalink -}}
5 <meta property="og:image" content="{{ $src }}">
6 <meta property="og:image:width" content="{{.Width}}" />
7 <meta property="og:image:height" content="{{.Height}}" />
8{{ end }}
Version 2
After doing some research i found another way - Generating images with post/page title. So i implemented this.

I stole some code from aarol.dev and updated it for my own purpose. This solution is a bit longer as it include also “writing text” to the image.
the code:
1 {{ $base := resources.Get "img/og_base.png" }}
2 {{ $mediumFont := resources.Get "/NotoSerif-Regular.ttf"}}
3 {{ $img := $base.Filter (images.Text .Page.Title (dict
4 "color" "#1e1e2e"
5 "size" 64
6 "linespacing" 2
7 "x" 100
8 "y" 291
9 "font" $mediumFont
10 ))}}
11 {{ $img = resources.Copy (path.Join .Page.RelPermalink "og.png") $img }}
12 <meta property="og:image" content="{{$img.Permalink}}">
13 <meta property="og:image:width" content="{{$img.Width}}" />
14 <meta property="og:image:height" content="{{$img.Height}}" />
If you don’t know where to get opengraph.html file - here it is on the official Hugo repository. This is the one I already use in some updated form.
Bonus: This is my current opengraph.html file:
ℹ️ Highlighted parts are those I added.
1{{ $font := resources.Get "/NotoSerif-Regular.ttf" }}
2{{ $text := "" }}
3
4<meta property="og:url" content="{{ .Permalink }}">
5
6{{- with or .Site.Title .Site.Params.title | plainify }}
7 <meta property="og:site_name" content="{{ . }}">
8{{- end }}
9
10{{- with or .Title .Site.Title .Site.Params.title | plainify }}
11 <meta property="og:title" content="{{ . }}">
12{{- end }}
13
14{{- with or .Description .Summary .Site.Params.description | plainify | htmlUnescape }}
15 <meta property="og:description" content="{{ trim . "\n\r\t " }}">
16{{- end }}
17
18{{- with or .Params.locale .Site.Language.Locale }}
19 <meta property="og:locale" content="{{ replace . `-` `_` }}">
20{{- end }}
21
22{{- if .IsHome }}
23 {{ $text = .Site.Params.Description }}
24{{- end }}
25
26{{- if .IsPage }}
27 {{ $text = .Page.Title }}
28 <meta property="og:type" content="article">
29 {{- with .Section }}
30 <meta property="article:section" content="{{ . }}">
31 {{- end }}
32 {{- $ISO8601 := "2006-01-02T15:04:05-07:00" }}
33 {{- with .PublishDate }}
34 <meta property="article:published_time" {{ .Format $ISO8601 | printf "content=%q" | safeHTMLAttr }}>
35 {{- end }}
36 {{- with .Lastmod }}
37 <meta property="article:modified_time" {{ .Format $ISO8601 | printf "content=%q" | safeHTMLAttr }}>
38 {{- end }}
39 {{- range .GetTerms "tags" | first 6 }}
40 <meta property="article:tag" content="{{ .Page.Title | plainify }}">
41 {{- end }}
42
43 {{ $base := resources.Get "img/og_base.png" }}
44 {{ $boldFont := resources.Get "/Inter-SemiBold.ttf"}}
45 {{ $mediumFont := resources.Get "/NotoSerif-Regular.ttf"}}
46 {{ $img := $base.Filter (images.Text .Page.Title (dict
47 "color" "#1e1e2e"
48 "size" 64
49 "linespacing" 2
50 "x" 100
51 "y" 291
52 "font" $mediumFont
53 ))}}
54 {{ $img = resources.Copy (path.Join .Page.RelPermalink "og.png") $img }}
55 <meta property="og:image" content="{{$img.Permalink}}">
56 <meta property="og:image:width" content="{{$img.Width}}" />
57 <meta property="og:image:height" content="{{$img.Height}}" />
58{{- else }}
59 <meta property="og:type" content="website">
60{{- end }}
61
62{{- with .Params.audio }}
63 {{- range . | first 6 }}
64 <meta property="og:audio" content="{{ . | absURL }}">
65 {{- end }}
66{{- end }}
67
68{{- with .Params.videos }}
69 {{- range . | first 6 }}
70 <meta property="og:video" content="{{ . | absURL }}">
71 {{- end }}
72{{- end }}
73
74{{- range .GetTerms "series" }}
75 {{- range .Pages | first 7 }}
76 {{- if ne $ . }}
77 <meta property="og:see_also" content="{{ .Permalink }}">
78 {{- end }}
79 {{- end }}
80{{- end }}
81
82{{- with .Site.Params.social }}
83 {{- if reflect.IsMap . }}
84 {{- with .facebook_app_id }}
85 <meta property="fb:app_id" content="{{ . }}">
86 {{- else }}
87 {{- with .facebook_admin }}
88 <meta property="fb:admins" content="{{ . }}">
89 {{- end }}
90 {{- end }}
91 {{- end }}
92{{- end }}