Some checks failed
🧪 CI (QA) / 🧪 Quality Assurance (push) Failing after 1m3s
- Restructure to pnpm monorepo (site moved to apps/web) - Integrate @mintel/tsconfig, @mintel/eslint-config, @mintel/husky-config - Implement Docker service architecture (Varnish, Directus, Gatekeeper) - Setup environment-aware Gitea Actions deployment
162 lines
3.5 KiB
Markdown
162 lines
3.5 KiB
Markdown
# 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)
|
|
```astro
|
|
---
|
|
// 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)
|
|
```astro
|
|
---
|
|
// 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)
|
|
```astro
|
|
---
|
|
// 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
|
|
```mdx
|
|
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
|
|
```astro
|
|
---
|
|
import YouTubeEmbed from '../components/Embeds/YouTubeEmbed.astro';
|
|
---
|
|
|
|
<YouTubeEmbed
|
|
videoId={post.videoId}
|
|
style="minimal"
|
|
className="mt-8 mb-12"
|
|
/>
|
|
```
|
|
|
|
## Styling Control
|
|
|
|
### CSS Variables
|
|
```css
|
|
.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
|
|
```html
|
|
<div data-style="minimal" data-aspect="square">
|
|
<!-- Custom styling via CSS -->
|
|
</div>
|
|
```
|
|
|
|
### Custom Classes
|
|
```astro
|
|
<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! |