Add partial to customize og:image meta property

Adds a new partial — `head/og-image.html` — that will render the value to be used
for `og:image` meta tags. The changes preserve the existing Hugo OpenGraph template's
behavior of checking and using the frontmatter or specific format of image names
as the `og:image` but if that doesn't work, it will delegate to the default partial which
uses `assets/images/og-image.{ext}` as the image.

This partial can be overriden to allow dynamic `og:image` URLs via a third-party service.

`_internal/opengraph.html` source is copied from Hugo to customize and support
this feature. Docs are updated to mention its usage.
This commit is contained in:
Sangeeth Sudheer 2025-03-15 15:16:41 +05:30
parent a7fc2d4a18
commit 1cbe2066ec
No known key found for this signature in database
GPG key ID: F6D06ECE734C57D1
3 changed files with 128 additions and 0 deletions

View file

@ -0,0 +1,94 @@
{{- /*
Original source: https://github.com/gohugoio/hugo/blob/61c39ae63b62667d965c2ff96d085f4eda59bcb2/tpl/tplimpl/embedded/templates/opengraph.html
*/ -}}
<meta property="og:url" content="{{ .Permalink }}">
{{- with or site.Title site.Params.title | plainify }}
<meta property="og:site_name" content="{{ . }}">
{{- end }}
{{- /* Source modified to remove pipe to `plainify` */ -}}
{{- with or .Title site.Title site.Params.title }}
<meta property="og:title" content="{{ . }}">
{{- end }}
{{- with or .Description .Summary site.Params.description | plainify | htmlUnescape }}
<meta property="og:description" content="{{ trim . "\n\r\t " }}">
{{- end }}
{{- with or .Params.locale site.Language.LanguageCode }}
<meta property="og:locale" content="{{ replace . `-` `_` }}">
{{- end }}
{{- if .IsPage }}
<meta property="og:type" content="article">
{{- with .Section }}
<meta property="article:section" content="{{ . }}">
{{- end }}
{{- $ISO8601 := "2006-01-02T15:04:05-07:00" }}
{{- with .PublishDate }}
<meta property="article:published_time" {{ .Format $ISO8601 | printf "content=%q" | safeHTMLAttr }}>
{{- end }}
{{- with .Lastmod }}
<meta property="article:modified_time" {{ .Format $ISO8601 | printf "content=%q" | safeHTMLAttr }}>
{{- end }}
{{- range .GetTerms "tags" | first 6 }}
<meta property="article:tag" content="{{ .Page.Title | plainify }}">
{{- end }}
{{- else }}
<meta property="og:type" content="website">
{{- end }}
{{- with partial "_funcs/get-page-images" . }}
{{- range . | first 6 }}
<meta property="og:image" content="{{ .Permalink }}">
{{- end }}
{{- else -}}
{{- /*
Source modified to load `assets/images/og-image.{webp,png,jpg}` files if any of them exists.
og-image.html can be modified in Hugo project if custom image generation logic is desired such
as using an external service.
*/ -}}
{{- if (and (or .IsHome .IsPage) (templates.Exists "partials/head/og-image.html")) -}}
{{- $ogImage := partial "head/og-image.html" . -}}
{{- with $ogImage -}}
<meta property="og:image" content="{{ . }}">
{{- end -}}
{{- end }}
{{- end }}
{{- with .Params.audio }}
{{- range . | first 6 }}
<meta property="og:audio" content="{{ . | absURL }}">
{{- end }}
{{- end }}
{{- with .Params.videos }}
{{- range . | first 6 }}
<meta property="og:video" content="{{ . | absURL }}">
{{- end }}
{{- end }}
{{- range .GetTerms "series" }}
{{- range .Pages | first 7 }}
{{- if ne $ . }}
<meta property="og:see_also" content="{{ .Permalink }}">
{{- end }}
{{- end }}
{{- end }}
{{- with site.Params.social }}
{{- if reflect.IsMap . }}
{{- with .facebook_app_id }}
<meta property="fb:app_id" content="{{ . }}">
{{- else }}
{{- with .facebook_admin }}
<meta property="fb:admins" content="{{ . }}">
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View file

@ -0,0 +1,5 @@
{{- if (or .IsHome .IsPage) -}}
{{- with resources.GetMatch "images/og-image.{webp,png,jpg}" -}}
{{- .RelPermalink -}}
{{- end -}}
{{- end -}}

View file

@ -97,6 +97,35 @@ faviconPath = 'your-path'
You can easily generate favicons using [this website](https://realfavicongenerator.net/) starting from your image.
[Here](https://github.com/tomfran/tomfran.github.io/tree/main/static) you can see an example of icons overriding default ones.
## OpenGraph
### Custom `og:image` (link preview images)
Typo allows you to customize the image shown in the card generated by most social media apps (X/Bluesky/WhatsApp) when you share a link to your site. These apps follow the [OpenGraph protocol](https://ogp.me) and look for `og:image` meta tags in the markup of the links you share. Typo will render the `og:image` meta tag provided a suitable one can be found.
> [!note]
> A size of 1200x630 is generally recommended for preview images.
A simple way to tell Hugo about the preferred image(s) to be used for `og:image` is by using the frontmatter `images` array with explicit paths to images. Otherwise, you can refer to [Hugo docs](https://gohugo.io/templates/embedded/#configuration-open-graph) on how the default template function looks for a suitable image. Typo respects and uses the image found in these aforementioned ways but otherwise, looks into the following cases.
To show the same preview image across all your pages not fitting the above conditions, copy the preview image to the location `/assets/images/og-image.png`. `.webp` and `.jpg` files are also supported. This image will usually be applied for links to the home page and other links without any explicitly specified images.
If you want more control, you can create your own `layouts/partials/head/og-image.html` in your Hugo project and provide custom templating to generate an image URL. Here's an example that shows how an externally hosted service could be used for links other than the home page:
```handlebars
{{- if .IsHome -}}
{{- with resources.GetMatch "images/og-image.{webp,png,jpg}" -}}
{{- .RelPermalink -}}
{{- end -}}
{{- else -}}
{{- if .IsPage -}}
{{- printf "/api/og-image?title=%s" (or .Title site.Title site.Params.title | urlquery) -}}
{{- end -}}
{{- end -}}
```
Overriding `og-image.html` will still respect frontmatter/Hugo processing config and only applies if those scenarios fail.
## Mermaid Diagrams
Mermaid diagrams are supported, just follow [this reference](https://gohugo.io/content-management/diagrams/#mermaid-diagrams) to use them. You can set Mermaid's light- and dark themes in your config; they switch with your blog's light/dark state. These are the defaults: