3.5 KiB
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
- Zero Client JS - Everything done at build time
- Fast Loading - Pre-rendered HTML
- SEO Friendly - Static content
- No External Dependencies - Only official APIs
- CDN Compatible - Works with any CDN
Next Steps
- Create embed components directory
- Implement YouTubeEmbed (simplest first)
- Implement TwitterEmbed (requires API setup)
- Create GenericEmbed for other platforms
- Add styling examples
- Document usage patterns
This gives you complete control while keeping everything free and fast!