Files
mintel.me/plans/embed-architecture.md
2026-01-14 17:15:10 +01:00

3.5 KiB

Build-Time Embed Architecture for Astro Blog

Overview

Complete solution for embedding tweets, YouTube videos, and other rich content with full styling control and build-time generation.

Architecture

1. Build-Time Embed Components

  • YouTubeEmbed.astro - Generates iframe at build time
  • TwitterEmbed.astro - Fetches tweet data at build time
  • GenericEmbed.astro - Handles any oEmbed provider
  • EmbedContainer.astro - Wrapper for consistent styling

2. Data Flow

Build Time:
1. Component receives props (videoId, tweetId, url)
2. Astro fetches embed data/API endpoints
3. Generates HTML with your custom styles
4. Injects into static page

Runtime:
- No external API calls
- Fast loading
- Full styling control

3. Key Features

  • Build-time generation - No client-side JS needed
  • Full styling control - CSS variables + custom classes
  • Lazy loading - Intersection Observer for performance
  • No paid services - Uses official APIs only
  • TypeScript support - Full type safety
  • Responsive - Mobile-first design

Implementation Strategy

YouTube (Simplest)

---
// Build time: Just generate iframe
const { videoId, className } = Astro.props;
const embedUrl = `https://www.youtube.com/embed/${videoId}`;
---

<div class={`youtube-embed ${className}`}>
  <iframe src={embedUrl} loading="lazy" />
</div>

Twitter (Requires API)

---
// Build time: Fetch tweet data via Twitter API
const { tweetId } = Astro.props;
const tweetData = await fetchTweetData(tweetId); // Uses oEmbed or API
---

<div class="twitter-embed">
  {tweetData.html}
</div>

Generic (oEmbed)

---
// Build time: Fetch oEmbed data
const { url } = Astro.props;
const oEmbedData = await fetchOEmbed(url);
---

<div class="generic-embed" set:html={oEmbedData.html} />

File Structure

src/
├── components/
│   └── Embeds/
│       ├── YouTubeEmbed.astro
│       ├── TwitterEmbed.astro  
│       ├── GenericEmbed.astro
│       ├── EmbedContainer.astro
│       └── index.ts

Usage Examples

In MDX/Markdown

import { YouTubeEmbed, TwitterEmbed } from '../components/Embeds';

# My Blog Post

<YouTubeEmbed 
  videoId="dQw4w9WgXcQ" 
  className="my-custom-style"
  aspectRatio="56.25%"
/>

<TwitterEmbed 
  tweetId="1234567890123456789"
  theme="dark"
/>

In Astro Templates

---
import YouTubeEmbed from '../components/Embeds/YouTubeEmbed.astro';
---

<YouTubeEmbed 
  videoId={post.videoId}
  style="minimal"
  className="mt-8 mb-12"
/>

Styling Control

CSS Variables

.youtube-embed {
  --aspect-ratio: 56.25%;
  --bg-color: #000;
  --border-radius: 12px;
  --shadow: 0 4px 12px rgba(0,0,0,0.15);
  --transition: all 0.3s ease;
}

Data Attributes

<div data-style="minimal" data-aspect="square">
  <!-- Custom styling via CSS -->
</div>

Custom Classes

<YouTubeEmbed className="custom-embed my-blog-style" />

Performance Benefits

  1. Zero Client JS - Everything done at build time
  2. Fast Loading - Pre-rendered HTML
  3. SEO Friendly - Static content
  4. No External Dependencies - Only official APIs
  5. CDN Compatible - Works with any CDN

Next Steps

  1. Create embed components directory
  2. Implement YouTubeEmbed (simplest first)
  3. Implement TwitterEmbed (requires API setup)
  4. Create GenericEmbed for other platforms
  5. Add styling examples
  6. Document usage patterns

This gives you complete control while keeping everything free and fast!