profileRyan KesPGP keyI build stuffEmailGithubTwitterLast.fmMastodonMatrix

How To Integrate Instagram Into Your Hugo Website

This is a quick tutorial to teach you how to integrate your Instagram feed into your hugo site 1. 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 part:

{{ $dataJ := getJSON (printf
"https://api.instagram.com/v1/users/self/media/recent/?access_token=%s"
.Site.Params.access_token) }} {{ range $dataJ.data }}
<a href="{{ .link }}" target="_new">
  <div
    class="cover-card col-sm-4"
    style="background: url({{ .images.standard_resolution.url }}) no-repeat center top;background-size:cover;"
  >
    <p>
      {{ with .caption }} {{ .text }}<br />-<br />
      {{ end }}
      <span class="play-date" data-date="{{ .created_time }}"></span>
    </p>
  </div>
</a>
{{ end }}

On line 1-3 we connect to the Instagram api with 1 parameter:

This returns something like:

{
  "pagination": {
    "next_url": "https://api.instagram.com/v1/users/30589186/media/recent?access_token=30589186.1677ed0.04f23d0cd29246d692e1f240b0fd836a\u0026count=1\u0026max_id=1352196774743616727_30589186",
    "next_max_id": "1352196774743616727_30589186"
  },
  "meta": {
    "code": 200
  },
  "data": [
    {
      "attribution": null,
      "tags": ["test", "hugo", "wercker", "ifttt"],
      "type": "image",
      "location": null,
      "comments": {
        "count": 0
      },
      "filter": "Amaro",
      "created_time": "1475414438",
      "link": "https://www.instagram.com/p/BLD981pBazX/",
      "likes": {
        "count": 3
      },
      "images": {
        "low_resolution": {
          "url": "https://scontent.cdninstagram.com/t51.2885-15/s320x320/e35/14488341_1365561496789352_8898975373191020544_n.jpg?ig_cache_key=MTM1MjE5Njc3NDc0MzYxNjcyNw%3D%3D.2",
          "width": 320,
          "height": 320
        },
        "thumbnail": {
          "url": "https://scontent.cdninstagram.com/t51.2885-15/s150x150/e35/14488341_1365561496789352_8898975373191020544_n.jpg?ig_cache_key=MTM1MjE5Njc3NDc0MzYxNjcyNw%3D%3D.2",
          "width": 150,
          "height": 150
        },
        "standard_resolution": {
          "url": "https://scontent.cdninstagram.com/t51.2885-15/s640x640/sh0.08/e35/14488341_1365561496789352_8898975373191020544_n.jpg?ig_cache_key=MTM1MjE5Njc3NDc0MzYxNjcyNw%3D%3D.2",
          "width": 640,
          "height": 640
        }
      },
      "users_in_photo": [],
      "caption": {
        "created_time": "1475414438",
        "text": "Which one to pick? #test #ifttt #wercker #hugo",
        "from": {
          "username": "alrayyes",
          "profile_picture": "https://scontent.cdninstagram.com/t51.2885-19/11821796_875675509184288_365567230_a.jpg",
          "id": "30589186",
          "full_name": ""
        },
        "id": "17842838194149837"
      },
      "user_has_liked": false,
      "id": "1352196774743616727_30589186",
      "user": {
        "username": "alrayyes",
        "profile_picture": "https://scontent.cdninstagram.com/t51.2885-19/11821796_875675509184288_365567230_a.jpg",
        "id": "30589186",
        "full_name": ""
      }
    }
  ]
}

Lines 3 - 16 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 ifttt to trigger a build every time I upload a photo.

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


  1. You really shouldn't be using products owned by Facebook. Personally I don't use Instagram anymore, and therefore don't have a working demo to show. At the time of writing Facebook is closing down the Instagram API so all of this probably won't work in the not too distant future.