Guide · Astro

Add an Instagram feed to Astro

Two ways to show a live Instagram feed on an Astro site: drop the widget script into any .astro template (one directive to know about), or fetch the public JSON API in frontmatter and render the posts with your own markup.

1Get your feed ID

Create a free Simpleembed account, connect your Instagram Business or Creator account, and create a feed. On the Feeds page, open the Embed code dialog — the data-feed-id value in the snippet is your feed ID.

2Option A: paste the widget script

Astro processes and bundles <script> tags by default, so add the is:inline directive to ship the embed snippet untouched. Place it in any .astro page, layout, or component where the feed should appear:

---
// src/pages/index.astro — or any .astro component
---

<script
  is:inline
  src="https://simpleembed.com/embed.js"
  data-feed-id="YOUR_FEED_ID"
  async
></script>

That's the whole integration — the widget renders a responsive grid in place of the script tag, resizes itself, and stays in sync with your Instagram account.

3Option B: fetch the JSON API in frontmatter

For full control over markup and styling, fetch the feed's public JSON endpoint in component frontmatter and render the posts statically:

---
// src/components/InstagramGrid.astro — fetched at build time (or per request with SSR)
type FeedResponse = {
  feed: { id: string; name: string; source: string };
  posts: Array<{
    id: string;
    mediaType: "IMAGE" | "VIDEO" | "CAROUSEL_ALBUM";
    caption: string | null;
    permalink: string;
    imageUrl: string;
    timestamp: string;
    childCount: number;
  }>;
};

const res = await fetch("https://simpleembed.com/api/feeds/YOUR_FEED_ID");
const { posts }: FeedResponse = await res.json();
---

<div class="ig-grid">
  {posts.map((post) => (
    <a href={post.permalink} target="_blank" rel="noreferrer">
      <img src={post.imageUrl} alt={post.caption ?? "Instagram post"} loading="lazy" />
    </a>
  ))}
</div>

<style>
  .ig-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
  }
  .ig-grid img {
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
  }
</style>

On a static build the posts are captured at build time and stay frozen until the next deploy; with an SSR adapter the fetch runs per request instead. Always render images through imageUrl — it proxies Instagram's CDN so images never expire.

Using React islands via @astrojs/react? The simpleembed-react npm package works there too: <InstagramFeed client:load feedId="..." />.

Customize it

If you use the widget, layout, post count, and styling live in your Simpleembed dashboard — change a setting there and the embed updates in place, no rebuild required. The frontmatter route is the opposite trade: you own the markup, so customization happens in your components.

Frequently asked questions

Why does the guide use is:inline on the script tag?
Astro processes and bundles <script> tags by default, which would break an external widget loader. is:inline tells Astro to ship the tag to the browser exactly as written. Astro actually implies is:inline when a script has attributes beyond src (like data-feed-id), but writing it explicitly makes the intent clear and survives refactors.
Widget or build-time fetch — which should I use?
The widget stays live: new Instagram posts appear within minutes with no rebuild. The build-time fetch gives you full control of the markup, but on a static site the posts are frozen until your next build — pair it with scheduled deploys or an SSR adapter if freshness matters.
Does the JSON API approach work with SSR adapters?
Yes. On a server-rendered route (Node, Vercel, Netlify, or Cloudflare adapters) the frontmatter fetch runs per request, and the API response is CDN-cached for about five minutes, so it stays fast and current.
Can I use Astro's <Image /> component with the API's imageUrl?
Yes. imageUrl points at Simpleembed's image proxy (so images never expire, unlike hotlinked Instagram CDN URLs). Add that host to image.domains in astro.config to let astro:assets optimize the remote images.
How much does Simpleembed cost?
One Instagram source and one feed are free forever, including API access. The $7/month plan unlocks unlimited feeds and sources.

Get your feed ID in about two minutes

Create a free Simpleembed account, connect your Instagram Business or Creator account, and copy your embed snippet. One source and one feed are free forever; $7/month unlocks unlimited feeds, sources, and views.

Start free