Random Cover Image

Time 4 minute read
Gray speaker on table near brown wooden pto (Photo by [Gabriel Beaudry](https://unsplash.com/@gbeaudry?utm_source=chringel.dev%20blog&utm_medium=referral) on [Unsplash](https://unsplash.com/?utm_source=chringel.dev%20blog&utm_medium=referral))
Gray speaker on table near brown wooden pto (Photo by Gabriel Beaudry on Unsplash)

This post is part of the Blogging with Hugo series.

This is a short one! A quick rundown on how I managed to get a random cover image for my blog posts when creating new content using Hugo.

Lately I’ve been writing blog posts where I was struggling to find a fitting cover image. I could just omit the cover image altogether, but I think every blog post should have a cover image (it also increases the click rate on social media, but *sshhh*). So I was wondering, is there a way to get a new random cover image, each time I create new content. I was already downloading images from Unsplash, so why not get a random image from their API?

You will need an account at Unsplash to use the API.

Link Post archetype

Archetypes in Hugo are templates for your content files. For example for a blog post, you can use predefined values for the front matter, and even use Hugo functions. And more interestingly, before the front matter you can put a lot of logic to get the variables you need.

My theme’s blog post front matter uses a special nested parameter to create the cover image and a caption:

cover:
  src: (hyper-)link-to-an-image
  caption: image caption

But you can also use it with Hugo’s default image parameter, all you need is the link to an image.

{{- $imageUrl := "" -}}
{{- $author := "" -}}
{{- $authorUrl := "" -}}
{{- $altDescription := "" -}}

{{- $unsplashAccessToken := getenv "HUGO_UNSPLASH_ACCESS_TOKEN" -}}
{{- $authorization := $unsplashAccessToken | printf "%s %s" "Client-ID" -}}
{{- $data := getJSON "https://api.unsplash.com/photos/random/?orientation=landscape" (dict "Authorization" $authorization) -}}

{{- with $data.urls -}}
  {{- $imageUrl = .raw -}}
{{- end -}}
{{- with $data.user -}}
  {{- $author = .name -}}
  {{- $authorUrl = .links.html -}}
{{- end -}}
{{- with $data.alt_description -}}
  {{ $altDescription = . | humanize}}
{{- end -}}

First, we define four variables $imageUrl, $author, $authorUrl and $altDescription.

{{- $imageUrl := "" -}}
{{- $author := "" -}}
{{- $authorUrl := "" -}}
{{- $altDescription := "" -}}

Unsplash’s guideline for attribution says, you need to properly attribute the image’s author coming from Unsplash. That’s why we need the author’s name and a link to their profile. For the image caption, we would like to use the image’s description.

Next, we authorize against Unsplash’s API and make a request to the random endpoint.

{{- $unsplashAccessToken := getenv "HUGO_UNSPLASH_ACCESS_TOKEN" -}}
{{- $authorization := $unsplashAccessToken | printf "%s %s" "Client-ID" -}}
{{- $data := getJSON "https://api.unsplash.com/photos/random/?orientation=landscape" (dict "Authorization" $authorization) -}}

When creating a developer account, you’ll receive your Access and Secret keys. Never share either of them publicly! I would recommend exporting your access key as an environment variable, i.e. HUGO_UNSPLASH_ACCESS_TOKEN. The next line builds the value for the authorization header, required for accessing the API. The last line sends a request and stores the response in the $data variable.

The last step is just assigning variables based on the JSON response object.

{{- with $data.urls -}}
  {{- $imageUrl = .raw -}}
{{- end -}}
{{- with $data.user -}}
  {{- $author = .name -}}
  {{- $authorUrl = .links.html -}}
{{- end -}}
{{- with $data.alt_description -}}
  {{ $altDescription = . | humanize}}
{{- end -}}

Now, we can use the variables in our front matter, i.e.:

cover:
  src: {{ $imageUrl }}
  caption: "{{ $altDescription }} (Photo by [{{ $author }}]({{ $authorUrl }}?utm_source=app_name&utm_medium=referral) on [Unsplash](https://unsplash.com/?utm_source=app_name&utm_medium=referral))"

You could also use this snippet as a Shortcode to generate an image based off a search term. The random endpoint mentioned above allows a query parameter, which you can pass search terms.

// layout/shortcodes/random-image.html

{{- $imageUrl := "" -}}
{{- $author := "" -}}
{{- $authorUrl := "" -}}
{{- $altDescription := "" -}}
{{- $query := .Get 0 -}}

{{- $unsplashAccessToken := getenv "HUGO_UNSPLASH_ACCESS_TOKEN" -}}
{{- $authorization := $unsplashAccessToken | printf "%s %s" "Client-ID" -}}
{{- $requestUrl := $query | printf "%s%s" "https://api.unsplash.com/photos/random/?query=" -}}
{{- $data := getJSON $requestUrl (dict "Authorization" $authorization) -}}

{{- with $data.urls -}}
  {{- $imageUrl = .raw -}}
{{- end -}}
{{- with $data.user -}}
  {{- $author = .name -}}
  {{- $authorUrl = .links.html -}}
{{- end -}}
{{- with $data.alt_description -}}
  {{ $altDescription = . | humanize}}
{{- end -}}

  <figure>
    <img
      alt="{{ $altDescription }}"
      title="{{ $altDescription }}"
      src="{{ $imageUrl }}"
    />
  </figure>
  <figcaption class="text-sm italic">
    <p>{{ $altDescription }} (Photo by <a href="{{ $authorUrl }}?utm_source=app_name&utm_medium=referral">{{ $author }}</a> on <a href="https://unsplash.com/?utm_source=app_name&utm_medium=referral">Unsplash</a>)</p>
  </figcaption>

Use the shortcode like this:

{{< random-image "sunset" >}}

This series

  1. Chringel Hugo Theme
  2. Inline SVG Icons For Hugo
  3. Isso - An Alternative Commenting System For Hugo
  4. umami - A Google Analytics Alternative For Hugo
  5. Automatically Deploy a Hugo Website to a Remote Host Using Github Actions
  6. Hugo Simple Post Archive
  7. Random Cover Image

Share Social Interact With This Post At: Logo Mastodon Mastodon Logo Twitter Twitter
Calendar Posted:
Person Posted By:
Folder Open Categories: Coding Tutorials

Reactions