Embedding an Instagram post in your website
Tags: tutorial, html, javascript, codenewbie
Published: 2020-09-12 17:37:46

#Introduction

Ever wanted to share an Instagram post to your website? It is remarkably easy. You only need to know **basic html** to share one. And it works for photos, videos, and even reels and IGTV! 

#Easy embedding to HTML.

* First, go to a post and click on the options "...".

![click on the ... dot at the top right](https://dev-to-uploads.s3.amazonaws.com/i/s9da6p6vafq52ieros02.png)

* And choose *Embed*.

![choose the embed option](https://dev-to-uploads.s3.amazonaws.com/i/9h2x2n8wo66v1wvgf65d.png)

* Then click on *Copy Embed code*.

![click on copy the embed code](https://dev-to-uploads.s3.amazonaws.com/i/bt7nn7gvp310eocgwua2.png)

#### Tada!

Now you have all you need to generate your post. Just paste it in your html and your post will be embedded into your website. 

**Note**: The embed post will adapt itself to the place it has. You can't really style it. But you can put it inside a parent container like a div and control its width for example.


![example of embedding a post](https://dev-to-uploads.s3.amazonaws.com/i/czk5gz0qky2pzv30s2a1.gif)

In this example I'm using **codepen** (online code editor) to paste the result and show the embedded post.

#Optional

The above is enough to share your Instagram post in your own website. 

Instagram also offers a dynamic embedding method. That way we can  **fetch the post from an instagram url and display it**.

But first, you'll need a facebook developer account and setup an app there (coz facebook owns Insta 😁). Sign up for one at [https://developers.facebook.com](https://developers.facebook.com/)

# Setup a Facebook app

We need a facebook app and add the oEmbed product that is going to generate the post to be embedded for us.

* Once logged in, choose *Create App*:

![click on create an app](https://dev-to-uploads.s3.amazonaws.com/i/2gq2icfrqor6qzzodxoi.png)

* Enter a name and email:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/v73z4271d97ebdsk0j5z.png)

* Go to the app dashboard and scroll down the products list to find oEmbed then click on *Set Up* to add it:

![find the oEmbed product](https://dev-to-uploads.s3.amazonaws.com/i/8f1wompxk1tpni52k2tn.png)

* Go to Settings > Advanced and copy the app ID and the client token for later use.

![app id and client token](https://dev-to-uploads.s3.amazonaws.com/i/xbr950ml9if9yjygbyfd.png)

Right next to the app ID is a switch that says **In development**. 

* Click to switch your app from development to **live**. Because oEmbed only work if the app is in live mode.

# Embedding the post dynamically.

This tutorial follow the [oEmbed guide](https://developers.facebook.com/docs/instagram/oembed/#oembed-product). We are going to focus on how to implement this on a static website with client-side fetch and no backend. For full stack devs, click on the guide above to see how to fetch code from backend.

We need to use the fetch api which works asynchronously. A basic knowledge of async/await could help. But I'll try to explain how it works in easy terms 😄.

## Step 1: fetch the instagram post

The url to be fetched look like this:
```javascript
"https://graph.facebook.com/v8.0/instagram_oembed?url=" + POST_URL + 
"&omitscript=true&access_token=" + APP_ID + "|" + CLIENT_TOKEN
```
Create variables POST_URL, APP_ID , CLIENT_TOKEN.

* POST_URL is the link to your post, just copy and paste the url bar of your post.

* Paste in your app id and client token. (In production, save those in environment variables to prevent everyone from accessing it)

* `omitscript=true` is needed to load the post ourselves to the DOM. I'll detail about it later on.

We are fetching with the built-in javascript [fetch api](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).

**Async/await** is used to run **asynchronous code**. Fetch is asynchronous as the response from fetch will take time to arrive.
To use async/await, we need to place async before declaring a function and add await right before the asynchronous part like this:

``` javascript
async function getPost() {
  var response = await fetch(
"https://graph.facebook.com/v8.0/instagram_oembed?url=" + 
POST_URL + "&omitscript=true&access_token=" + APP_ID + "|" + 
CLIENT_TOKEN)
}
```

The response from fetch comes as a JSON and need to be parsed into a javascript object with the [json() method](https://developer.mozilla.org/en-US/docs/Web/API/Body/json) like this:

``` javascript
response.json()
``` 

It's also asynchronous so we are adding await before it:

``` javascript
await response.json()
``` 
And we are going to save it in a `data` variable
``` javascript
async function getPost() {
  var response = await fetch(
"https://graph.facebook.com/v8.0/instagram_oembed?url=" + 
POST_URL + "&omitscript=true&access_token=" + APP_ID + "|" + 
CLIENT_TOKEN)
  var data = await response.json()
}
```

* `data` holds the object we fetched from Instagram. It has the following form:
```javascript
{
  "version": "1.0",
  "author_name": "diegoquinteiro",
  "provider_name": "Instagram",
  "provider_url": "https://www.instagram.com/",
  "width": 658,
  "html": "<blockquote class=\"instagram-media\" data-instgrm-ca...",
  "thumbnail_width": 640,
  "thumbnail_height": 640
}
```

The `html` property holds the post to be embedded. 

* Save `html` in a variable named `myPostHtml`:
```javascript
var myPostHtml = data.html
```

## Step 2: display the post

The hardest part is over. Now let's add it to the HTML.

Let's say we have a div with a class of post like
```html
<div class="post"></div>
```
We will add `myPostHtml` to the div with a class of `post` with:
```javascript
var post = document.querySelector(".post")
post.innerHTML = myPostHtml 
```

And finally will be loading it. 

Remember in the fetch request we added `omitscript=true`? The script won't run when you add it dynamically so we had to omit it.
You'll need to include a copy of that script in your website. Following the guide above, here's the [link to the Instagram script](https://www.instagram.com/static/bundles/metro/EmbedSDK.js/33cd2c5d5d59.js?fbclid=IwAR3asja2rHbvcnjCUehbSFMHng39Vyrrky12upuxrjNnt1J9_qoD5IG7gWk).

* Saved the file from this link in an *embed.js* file and add it as a script in your html code.

We can now used embed.js.
The load method we are going to call in our function is:
```javascript
  instgrm.Embeds.process()
```

We add this at the end of our function. The final javascript code look like this:

```javascript
var POST_URL = "my post url"
var APP_ID = "my app ID"
var CLIENT_TOKEN= "my client token"
var post = document.querySelector(".post")

async function getPost() {
  var response = await fetch(
"https://graph.facebook.com/v8.0/instagram_oembed?url=" + 
POST_URL + "&omitscript=true&access_token=" + APP_ID + "|" + 
CLIENT_TOKEN)
  var data = await response.json()
  var myPostHtml = data.html
  post.innerHTML = myPostHtml
  instgrm.Embeds.process()
}
```

By calling getPost() we will get an embed post to display where we want.

* If we want to display a post from an url a user enters we just need to replace POST_URL inside fetch() with the value of the user's input url. 

Example we added a text input with a class of `inputUrl`:

```javascript
var POST_URL = "my post url"
var APP_ID = "my app ID"
var CLIENT_TOKEN= "my client token"
var post = document.querySelector(".post")
var inputUrl = document.querySelector(".inputUrl")

async function getPost() {
  // get value from user input
  var url = inputUrl.value
  var response = await fetch(
"https://graph.facebook.com/v8.0/instagram_oembed?url=" + 
url + "&omitscript=true&access_token=" + APP_ID + "|" + 
CLIENT_TOKEN)
  var data = await response.json()
  var myPostHtml = data.html
  post.innerHTML = myPostHtml
  instgrm.Embeds.process()
}
```

# Improvements:

We would like to make it work with not just the post url from the address bar but also in case the user click on the copy link in the options:

![copy link](https://dev-to-uploads.s3.amazonaws.com/i/yfrumufynpwpyqhc4q0u.png)

As of now it won't work. Because at the end of the post url Instagram added a query like this:

"https://www.instagram.com/p/CFA8H3sob2_/?utm_source=ig_web_copy_link"

We need to remove the query part: "?utm_source=ig_web_copy_link" and only keep the post url. 
* We could use slice to remove it:

```javascript
  var url = inputUrl.value
  //remove ? and the part after it
  var indexOfQuery = url.indexOf("?")
  if (indexOfQuery !== -1) {
    url = url.slice(0, indexOfQuery)
  }
```

* Or regex:

```javascript
  var url = inputUrl.value
  //remove ? and the part after it
  url = url.replace(/\?.*$/, "")
```

And that's it!!

![final result](https://dev-to-uploads.s3.amazonaws.com/i/648d1uvafuvzgad1dmh6.gif)

#Thanks for reading 😁!!

&nbsp;