Marketplace Apps
The YouTube App for Agility enables users to seamlessly search, select, and embed YouTube videos directly into their content with automatic metadata fetching and live previews.
YouTube is the world's largest video hosting platform that enables you to deliver high-quality video experiences to your audience. With billions of videos, powerful analytics, and reliable streaming, YouTube is trusted by creators and businesses worldwide.
This integration makes publishing Agility content with YouTube videos quick and easy.
Renders a Video field that allows you to embed YouTube videos in your content.
When you click the field, you can paste any YouTube video URL, and the app will automatically fetch the video details and display a live preview.
The field supports various YouTube URL formats:
In order to use this integration, some set up is required.
You can install the app from the Settings / Apps section of Agility.
In order to use YouTube fields, you need to have Content Models or Page Modules in Agility CMS that utilize this new field type.
Add a YouTube field to any Content Model in Agility CMS:
Next, create some content using your Content Model:
Now that you've set up the field and allow editors to embed YouTube videos, the next thing you'll need to do is actually output these fields in your digital solution (i.e. website or app).
The value for a YouTube Video field will be a JSON string returned from the Content Fetch or GraphQL API.
In order to properly read your YouTube video data, you'll need to parse the string to an object.
In JavaScript, this can be accomplished using JSON.parse(youtubeVideoFieldValue).
{
// The original YouTube URL
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
// Video title
"title": "Rick Astley - Never Gonna Give You Up (Official Video)",
// Author information (channel)
"author_name": "Rick Astley",
"author_url": "https://www.youtube.com/@RickAstleyYT",
// Video type
"type": "video",
// Video dimensions
"height": 360,
"width": 640,
// API version
"version": "1.0",
// Provider information
"provider_name": "YouTube",
"provider_url": "https://www.youtube.com/",
// Thumbnail information
"thumbnail_height": 360,
"thumbnail_width": 480,
"thumbnail_url": "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg",
// Embed HTML code
"html": "<iframe width=\"640\" height=\"360\" src=\"https://www.youtube.com/embed/dQw4w9WgXcQ?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>",
// YouTube video ID
"video_id": "dQw4w9WgXcQ"
}
}
Here's an example of how to render a YouTube video field in a Next.js application:
import React from "react"
const YouTubeVideo = ({ fieldValue }) => {
// Parse the JSON string
const videoData = JSON.parse(fieldValue)
if (!videoData || !videoData.video_id) {
return null
}
return (
<div className="youtube-video">
<h2>{videoData.title}</h2>
{/* Responsive video container */}
<div
className="video-container"
style={{
position: "relative",
paddingBottom: "56.25%", // 16:9 aspect ratio
height: 0,
overflow: "hidden"
}}
>
<iframe
src={`https://www.youtube.com/embed/${videoData.video_id}`}
style={{
position: "absolute",
top: 0,
left: 0,
width: "100%",
height: "100%"
}}
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
/>
</div>
{/* Video metadata */}
{videoData.author_name && (
<p className="author">
By{" "}
<a href={videoData.author_url} target="_blank" rel="noopener noreferrer">
{videoData.author_name}
</a>
</p>
)}
</div>
)
}
export default YouTubeVideo
For more advanced use cases, you can use the official YouTube Player API to have programmatic control over the video player:
import React, { useEffect, useRef } from "react"
const YouTubePlayerAdvanced = ({ fieldValue }) => {
const videoData = JSON.parse(fieldValue)
const playerRef = useRef(null)
const youtubePlayerRef = useRef(null)
useEffect(() => {
// Load the YouTube Player API
if (!window.YT) {
const tag = document.createElement("script")
tag.src = "https://www.youtube.com/iframe_api"
const firstScriptTag = document.getElementsByTagName("script")[0]
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag)
}
// Initialize the YouTube player when API is ready
window.onYouTubeIframeAPIReady = () => {
if (playerRef.current && videoData.video_id) {
youtubePlayerRef.current = new window.YT.Player(playerRef.current, {
videoId: videoData.video_id,
width: 640,
height: 360,
events: {
onReady: (event) => {
console.log("YouTube player ready")
},
onStateChange: (event) => {
if (event.data === window.YT.PlayerState.PLAYING) {
console.log("Video started playing")
}
if (event.data === window.YT.PlayerState.ENDED) {
console.log("Video ended")
}
}
}
})
}
}
// If API is already loaded
if (window.YT && window.YT.Player) {
window.onYouTubeIframeAPIReady()
}
// Cleanup
return () => {
if (youtubePlayerRef.current && youtubePlayerRef.current.destroy) {
youtubePlayerRef.current.destroy()
}
}
}, [videoData.video_id])
return (
<div>
<h2>{videoData.title}</h2>
<div ref={playerRef}></div>
</div>
)
}
export default YouTubePlayerAdvanced
To use the YouTube Player API, you don't need to install additional packages as it's loaded directly from YouTube:
<!-- The API script is loaded automatically in the component above -->
<script src="https://www.youtube.com/iframe_api"></script>
You can also use the thumbnail URL to display video previews in listings or grids:
const VideoThumbnail = ({ fieldValue }) => {
const videoData = JSON.parse(fieldValue)
return (
<div className="video-thumbnail">
<img
src={videoData.thumbnail_url}
alt={videoData.title}
width={videoData.thumbnail_width}
height={videoData.thumbnail_height}
/>
<h3>{videoData.title}</h3>
<p>Channel: {videoData.author_name}</p>
</div>
)
}
YouTube provides official APIs and libraries to help you work with their platform:
For comprehensive documentation and advanced features, visit the YouTube Developers Portal.
loading="lazy" attribute on iframes (where supported)youtube-nocookie.com) for GDPR complianceFor issues related to: