If you run a website and want to include an Instagram Reel or Post, embedding is almost always a better choice than downloading and re-hosting. Embeds are free, always legal, give the creator credit and view counts, and keep working even if Instagram changes its CDN. This guide covers the official embed method, two fallbacks, and the exact performance numbers you should care about.
Method 1: Official Instagram embed (recommended)
Instagram exposes an oEmbed endpoint that returns an HTML snippet you can drop into your page. The snippet is an <iframe> plus a script tag that loads embed.js.
Step 1: Get the embed code from the app
Open the Reel or Post on instagram.com in a desktop browser. Click the three-dots menu on the post and choose Embed. Instagram copies an HTML snippet to your clipboard that looks like this:
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/reel/CODE/" ...></blockquote><script async src="https://www.instagram.com/embed.js"></script>
Step 2: Paste into your page HTML
Drop the snippet into your page source wherever you want the Reel to appear. The first load pulls the embed.js script (25 KB), which then replaces the blockquote with a full iframe player. No API key, no authentication, no rate limit for individual pages.
Step 3: Handle the lazy loading
The default embed loads eagerly, which hurts Core Web Vitals on pages with several embeds. Add loading="lazy" to the iframe after it appears, or use Intersection Observer to load the script only when the blockquote enters the viewport. Our blog uses the second approach and saw LCP drop from 3.8 s to 1.4 s on Reel-heavy pages.
Method 2: oEmbed API (for CMS integrations)
If you are building a WordPress plugin or a headless CMS, call the oEmbed endpoint directly:
https://graph.facebook.com/v19.0/instagram_oembed?url=INSTAGRAM_URL&access_token=APP_ACCESS_TOKEN
The response is JSON containing title, author_name, html, thumbnail_url, width and height. You need a Facebook App access token — register a free Facebook developer account, create an app, and generate a client-credentials token. The rate limit is 200 calls per hour per token.
Method 3: Screenshot + link (minimum viable fallback)
If all embedding methods fail (e.g. Meta blocks your region), take a screenshot of the Reel thumbnail, upload it to your own server, and link the image to the original Instagram URL. This is the only method that makes a local copy, so use it sparingly and always credit the creator in the alt text.
Performance numbers
I measured three pages with increasing embed counts on a median mobile connection:
| Embeds per page | LCP (lazy) | LCP (eager) | Transfer size |
|---|---|---|---|
| 1 | 1.2 s | 1.9 s | 48 KB |
| 5 | 1.4 s | 3.8 s | 180 KB |
| 10 | 1.6 s | 6.2 s | 340 KB |
| 20 | 2.0 s | timeout | 660 KB |
The lesson: lazy-load embeds always. Eager loading kills your Core Web Vitals on any page with more than a handful of Reels.
Legal safety
Instagram's Platform Terms explicitly allow embedding public content via the official oEmbed endpoint. Courts have also confirmed the "server test" — Perfect 10 v Amazon (US) and Hyperlink cases in the EU — which holds that embedding is not a reproduction because the content is served from the original host. Embedding is the safest way to use Instagram content on your site.