profileRyan KesPGP keyI build stuffEmailGithubTwitterLast.fmMastodon

How To Integrate Last.fm Into Your Hugo Website

This is a quick tutorial to teach you how to integrate your Last.fm feed into your hugo site. To keep things nice and simple I've created a demo theme to get you started.

The demo is basically a one-page template. The important:

{{ $dataJ := getJSON (printf "https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=%s&api_key=%s&format=json&limit=%s" .Site.Params.username .Site.Params.apikey (.Site.Params.limit) ) }}
{{ range $dataJ.recenttracks.track }}
    <a href="{{ .url }}" target="_new">
        <div class="cover-card col-sm-4" style="background: url({{ range last 1 .image }}{{ index . "#text" }}{{ end }}) no-repeat center top;background-size:cover;">
            <p>
                {{ printf "%s - %s" (index .artist "#text") .name }}<br>
                -<br>
                {{ if isset .date "#text" }}<span class="play-date" data-date="{{ (index .date "uts") }}">{{ index .date "#text" }}</span>{{ else }}<span class="play-date" data-date="">Now playing...</span>{{ end }}
            </p>
        </div>
    </a>
{{ end }}

On line 1 we connect to the Last.fm api with 3 parameters:

  1. username
  2. limit (aka how many results do you want with a maximum of 200)
  3. api key (which you can get here)

This returns something like:

{
  "recenttracks": {
    "track": [
      {
        "artist": {
          "#text": "Years Years",
          "mbid": ""
        },
        "name": "1977",
        "streamable": "0",
        "mbid": "",
        "album": {
          "#text": "Communion",
          "mbid": ""
        },
        "url": "https://www.last.fm/music/Years++Years/_/1977",
        "image": [
          {
            "#text": "https://lastfm-img2.akamaized.net/i/u/34s/bcf1058b23fb9871695ac9e57582e095.png",
            "size": "small"
          },
          {
            "#text": "https://lastfm-img2.akamaized.net/i/u/64s/bcf1058b23fb9871695ac9e57582e095.png",
            "size": "medium"
          },
          {
            "#text": "https://lastfm-img2.akamaized.net/i/u/174s/bcf1058b23fb9871695ac9e57582e095.png",
            "size": "large"
          },
          {
            "#text": "https://lastfm-img2.akamaized.net/i/u/300x300/bcf1058b23fb9871695ac9e57582e095.png",
            "size": "extralarge"
          }
        ],
        "date": {
          "uts": "1475601846",
          "#text": "04 Oct 2016, 17:24"
        }
      }
    ],
    "@attr": {
      "user": "alrayyes",
      "page": "1",
      "perPage": "1",
      "totalPages": "175083",
      "total": "175083"
    }
  }
}

Lines 2 - 12 basically just loop through this json and output corresponding html.

The rest of the html is basically styling and using momentjs to generate pretty human readable datetimes. There is one small caveat though, as the generated site is static you need to rebuild it sporadically to keep the scrobbles up to date. I accomplish this using a cron job to trigger wercker.

That's all there is to it. The same principle can also be used to integrate Instagram into your site. Hopefully this tutorial was clear and concise enough. If not please let me know in the comments below.