Instagram Widget

July 23rd, 2019

As of this writing, Instagram has an API available that gets the first post from any public account. I was asked to embed the most recent post from a public Instagram account automatically on a page and stumbled into finding the Instagram API. It was a pleasant surprise that it didn't require authentication or any hassle at all. Here's the working example that loads the latest post from my cats' Instagram.

In my GitHub repo I have two HTML files. One (EmbedInstagramWidget) contains all the code to embed it directly by itself. The index.html is the standard approach and loads main.js and styles.css. I've included all the code below but feel free to grab it directly from GitHub if you want.

I used the HTML to just create a element for every aspect to be populated by the information from Instagram. Below is just the body of my HTML file.

1<div class="instagram-container">
2 <div id='instagram-post'>
3 <div class='header'></div>
4 <div class='imageContent'></div>
5 <div class='hoverCard'></div>
6 <div class='feedback'></div>
7 <div class='likes'></div>
8 <div class='instagramCaption'></div>
9 <div class='footer'></div>
10 <div class='error'></div>
11 </div>
12</div>

In the JavaScript, I basically call the API and get the information and then walk through populating each part of the page with it. The most important thing to update is the instagramUsername variable.

1var instagramUsername = 'minneyandmaxthecats'
2var httpRequest
3function GetLatestPost() {
4 var url = 'https://www.instagram.com/' + instagramUsername + '/?__a=1';
5 httpRequest = new XMLHttpRequest()
6 if (!httpRequest) {
7 alert('Giving up :( Cannot create an XMLHTTP instance')
8 }
9 httpRequest.onreadystatechange = requestHandleStateChange
10 httpRequest.open('GET', url)
11 httpRequest.send()
12}
13
14function numberWithCommas(x) {
15 return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
16}
17
18function requestHandleStateChange() {
19 if (httpRequest.readyState === XMLHttpRequest.DONE) {
20 if (httpRequest.status === 200) {
21 onQuerySucceeded(JSON.parse(httpRequest.responseText))
22 } else {
23 onQueryFailed()
24 }
25 }
26}
27
28function onQuerySucceeded(data) {
29 // need to build the content for the web part
30 var userInformation = data.graphql.user;
31 var latestPost = userInformation.edge_owner_to_timeline_media.edges[0].node;
32 var embedUrlRedirect = 'https://www.instagram.com/' + instagramUsername + '/?utm_source=ig_embed'
33
34 // header
35 var headerHTML = document.getElementsByClassName('header')[0];
36 var headerInnerHTML = '' +
37 '<div class="avatarContainer">' +
38 '<a href="' + embedUrlRedirect + '" target="_blank">' +
39 '<img src="' + userInformation.profile_pic_url + '" alt="' + instagramUsername + '">' +
40 '</a>' +
41 '</div>' +
42 '<div class="headerTextContainer">' +
43 '<a href="' + embedUrlRedirect + '" target="_blank">' +
44 '<span class="username">' + instagramUsername + '</span>' +
45 '</a>' +
46 '<div class="followerCount">' +
47 '<span>' + numberWithCommas(userInformation.edge_followed_by.count) + ' followers</span>' +
48 '</div>' +
49 '</div>' +
50 '<div class="viewProfileButtonContainer">' +
51 '<a class="ViewProfileButton" href="' + embedUrlRedirect + '">View Profile</a>' +
52 '</div>' +
53 '';
54 headerHTML.innerHTML = headerInnerHTML;
55
56 // imageContent
57 var imageContentHTML = document.getElementsByClassName('imageContent')[0];
58 var imageContentInnerHTML = '' +
59 '<a href="' + embedUrlRedirect + '" target="_blank">' +
60 '<img src="' + latestPost.thumbnail_src + '" alt="' + latestPost.accessibility_caption + '">' +
61 '</a>' +
62 '';
63 imageContentHTML.innerHTML = imageContentInnerHTML;
64
65 // hoverCard
66 var hoverCardHTML = document.getElementsByClassName('hoverCard')[0];
67 var hoverCardInnerHTML = '' +
68 '<div class="primaryText">' +
69 '<a href="' + embedUrlRedirect + '" target="_blank">View More on Instagram</a>' +
70 '</div>' +
71 '';
72 hoverCardHTML.innerHTML = hoverCardInnerHTML;
73
74 // likes
75 var likesHTML = document.getElementsByClassName('likes')[0];
76 var likesInnerHTML = '' +
77 '<a href="' + embedUrlRedirect + '" target="_blank">' + numberWithCommas(latestPost.edge_liked_by.count) + ' likes</a>' +
78 '';
79 likesHTML.innerHTML = likesInnerHTML;
80
81 // caption
82 var captionHTML = document.getElementsByClassName('instagramCaption')[0];
83 var captionInnerHTML = '' +
84 '<a href="' + embedUrlRedirect + '" target="_blank">' + instagramUsername + '</a>' +
85 '<br><br>' + latestPost.edge_media_to_caption.edges[0].node.text +
86 '';
87 captionHTML.innerHTML = captionInnerHTML;
88}
89
90function onQueryFailed() {
91 var errorContainer = document.getElementsByClassName('error')[0];
92 errorContainer.innerHTML = '<div>An error occured while retrieving ' + instagramUsername + '\'s latest post.</div><div>To view the latest posts, click <a href="https://www.instagram.com/' + instagramUsername + '" target="_blank">here</a> to view ' + instagramUsername + '\'s profile.</div>';
93}
94
95GetLatestPost();

The styles can be updated anyway you want them to appear. I set the background color, link color, and font style to match my website styles. They can be anything you want them to be :)

1html body {
2 font-family: 'Roboto Slab', serif;
3 background-color: #343a40;
4}
5a {
6 color: #3f88c5;
7 text-decoration: none;
8}
9a:hover {
10 text-decoration: underline;
11}
12.instagram-container {
13 width: 100%;
14}
15#instagram-post {
16 width: 530px;
17 margin: auto;
18 background: #fff;
19 border-radius: 3px;
20 border: 1px solid rgb(219, 219, 219);
21 box-shadow: none;
22 display: block;
23 padding: 0px;
24}
25/* header styles */
26#instagram-post .header {
27 height: 54px;
28 display: flex;
29 flex-direction: row;
30 align-items: center;
31 padding: 10px
32}
33#instagram-post .header .avatarContainer {
34 padding: 2px;
35 border-radius: 50%;
36}
37#instagram-post .header .avatarContainer img{
38 border-radius: 50%;
39 width: 30px;
40 height: 30px;
41}
42#instagram-post .header .headerTextContainer {
43 margin: 0 10px;
44 overflow: hidden;
45 flex-shrink: 1;
46 flex-grow: 1;
47}
48#instagram-post .header .headerTextContainer .username {
49 font-weight: 600;
50 text-overflow: ellipsis;
51 width: calc(100% - 21px);
52 white-space: nowrap;
53 display: block;
54}
55#instagram-post .header .headerTextContainer .followerCount {
56 color: #999;
57 line-height: 14px;
58 font-size: 12px;
59}
60#instagram-post .header .viewProfileButtonContainer {
61 margin-left: 15px;
62 flex: 1 1 auto;
63 display: flex;
64 flex-flow: row;
65 justify-content: flex-end;
66}
67#instagram-post .header .viewProfileButtonContainer a.ViewProfileButton{
68 margin-left: 10px;
69 background-color: #6D6E71;
70 border-radius: 3px;
71 color: #fff;
72 font-weight: 600;
73 padding: 5px 12px;
74 text-decoration: none;
75}
76#instagram-post .header .viewProfileButtonContainer a.ViewProfileButton:hover{
77 background-color: #333;
78 text-decoration: none;
79}
80/* image styles */
81#instagram-post .imageContent {
82 position: relative;
83 padding-bottom: 100%;
84}
85#instagram-post .imageContent a {
86 position: absolute;
87 top: 0;
88 right: 0;
89 bottom: 0;
90 left: 0;
91 background-color: #fafafa;
92}
93#instagram-post .imageContent a > img {
94 width: 100%;
95}
96/* hoverCard styles */
97#instagram-post .hoverCard .primaryText {
98 background-color: #fff;
99 border-bottom: 1px solid #efefef;
100 height: 44px;
101 margin-left: 12px;
102 margin-right: 12px;
103}
104#instagram-post .hoverCard .primaryText a {
105 font-weight: 600;
106 font-size: 14px;
107 overflow: hidden;
108 text-overflow: ellipsis;
109 white-space: nowrap;
110 line-height: 45px;
111}
112/* likes styles */
113#instagram-post .likes {
114 padding: 6px 10px;
115}
116#instagram-post .likes a {
117 font-weight: 600;
118 color: #262626;
119 text-decoration: none;
120 font-size: 14px;
121
122}
123/* caption */
124#instagram-post .instagramCaption {
125 padding:0 10px 6px;
126}
127#instagram-post .instagramCaption a {
128 font-weight: 600;
129}

This was a quick and easy project I tackled but was really fun, too. I was glad I was asked to add this functionality to a page for someone. Feel free to use this for yourself. And let me know if you have any thoughts about it or run into issues with it.