A custom field application for Agility CMS that enables content editors to easily embed and manage YouTube videos directly within their content. Built with the Agility Apps SDK v2, this app provides a seamless experience for adding YouTube videos with automatic metadata fetching and live previews.
- Simple paste-and-go interface for YouTube URLs
- Supports multiple URL formats:
https://www.youtube.com/watch?v=dQw4w9WgXcQhttps://youtu.be/dQw4w9WgXcQhttps://youtube.com/embed/dQw4w9WgXcQhttps://m.youtube.com/watch?v=dQw4w9WgXcQ
- Automatic video ID extraction and validation
- Uses YouTube's public oEmbed API to retrieve:
- Video title
- Thumbnail image
- Video dimensions (width/height)
- Author information (channel name and URL)
- Provider information
- No API keys required for public videos
- Embedded YouTube player using YouTube's standard embed iframe
- Full playback controls
- Responsive player that adapts to container size
- Support for all YouTube player features
- Desktop (β₯600px): Side-by-side layout with video and details
- Mobile (<600px): Stacked layout for optimal mobile viewing
- Automatically adjusts iframe height using
useResizeHeight()
- Stores full video metadata as structured JSON
- Easy access to video information in templates and API responses
- Persistent storage across content edits
-
Clone the repository
git clone https://github.com/agility/agility-cms-app-youtube.git cd agility-cms-app-youtube -
Install dependencies
npm install # or yarn install -
Run the development server
npm run dev # or yarn dev -
Open in browser Navigate to http://localhost:3001
- Navigate to
/fields/youtube-fieldin your browser - Paste a YouTube URL (try:
https://www.youtube.com/watch?v=dQw4w9WgXcQ) - Click "Fetch" to load the video
- Preview the video and see the metadata
app/
βββ fields/
β βββ youtube-field/
β βββ page.tsx # Main YouTube field component
βββ api/
β βββ app-uninstall/
β β βββ route.ts # Uninstall webhook handler
β βββ hello/
β βββ route.ts # Health check endpoint
βββ layout.tsx # Root layout with permissions policy
βββ page.tsx # Home page with app documentation
components/
βββ CommonDashboard.tsx # Shared dashboard component
public/
βββ .well-known/
βββ agility-app.json # App definition file
styles/
βββ globals.css # Global styles with Tailwind
{
"@agility/app-sdk": "^2.1.0",
"next": "16.0.0",
"react": "19.2.0",
"typescript": "^5.5.4"
}Access SDK functionality and field data:
const { initializing, fieldValue } = useAgilityAppSDK()Automatically adjust iframe height:
const containerRef = useResizeHeight(10)
return <div ref={containerRef}>...</div>Save video data to the field:
contentItemMethods.setFieldValue({
value: JSON.stringify(videoData)
})The field stores video data as JSON:
interface YouTubeVideoData {
url: string
title: string
author_name: string
author_url: string
type: string
height: number
width: number
version: string
provider_name: string
provider_url: string
thumbnail_height: number
thumbnail_width: number
thumbnail_url: string
html: string
video_id: string
}// Using the YouTube Player API
const loadYouTubePlayer = (videoId: string) => {
// Load the YouTube Player API
const tag = document.createElement("script")
tag.src = "https://www.youtube.com/iframe_api"
document.head.appendChild(tag)
// Initialize player when API is ready
window.onYouTubeIframeAPIReady = () => {
new window.YT.Player("player", {
videoId: videoId,
width: 640,
height: 360,
events: {
onReady: (event) => {
console.log("Player is ready")
}
}
})
}
}The app includes proper Permissions Policy headers to avoid browser console warnings:
// next.config.js
headers: [
{
key: "Permissions-Policy",
value: "autoplay=*, encrypted-media=*, fullscreen=*, clipboard-write=*, web-share=*"
}
]Permissions enabled:
- autoplay: Allow video autoplay
- encrypted-media: Support DRM content
- fullscreen: Enable fullscreen video
- clipboard-write: Allow copying URLs
- web-share: Enable sharing features
The app definition is served at /.well-known/agility-app.json and includes:
{
"name": "YouTube Video Field",
"version": "1.0.0",
"description": "Embed and manage YouTube videos",
"surfaces": {
"fields": [
{
"name": "youtube-field",
"displayName": "YouTube Video",
"path": "/fields/youtube-field"
}
]
}
}Check the browser console for errors:
- "Invalid YouTube URL": URL format is incorrect
- "Failed to fetch video data": Video may be private or network issue
- "Unable to load video player": Player initialization failed
Permissions policy warnings have been resolved. If you still see them:
- Clear browser cache
- Restart development server
- Check
next.config.jsheaders configuration
Use these URLs for testing:
https://www.youtube.com/watch?v=dQw4w9WgXcQhttps://youtu.be/jNQXAC9IVRw
See YOUTUBE_FIELD_USAGE.md for detailed debugging information.
- YOUTUBE_FIELD_USAGE.md - Detailed usage guide
- Agility CMS Apps Documentation
- Agility Apps SDK v2
- YouTube Player API
- YouTube oEmbed API
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License.
- Built with Agility CMS
- Video player by YouTube
- Powered by Next.js
- Styled with Tailwind CSS
Made with β€οΈ for the Agility CMS community