Overview
The Nadie Sabe Nada podcast app features automatic YouTube integration that finds and displays video versions of podcast episodes. When viewing an episode’s detail page, the app searches for the corresponding YouTube video and embeds it directly in the page.
YouTube integration is automatic - no manual searching required. The app finds the matching video for each episode.
How It Works
Automatic Video Discovery
When you open an episode detail page, the app automatically searches YouTube for the corresponding video:
const fetchYoutubeVideo = async () => {
if (foundPodcast) {
try {
const response = await fetch(
`https://www.googleapis.com/youtube/v3/search?part=snippet&q=${encodeURIComponent(
foundPodcast.title
)}&key=${YT_API_KEY}&channelId=${CHANNEL_ID}&type=video&maxResults=1`
);
const data = await response.json();
if (data.items && data.items.length > 0) {
setYoutubeVideoId(data.items[0].id.videoId);
}
} catch (error) {
console.error("Error fetching YouTube video:", error);
}
} else {
navigate("/404");
}
};
Search Parameters
The YouTube API search uses these parameters:
- part:
snippet - Returns basic video information
- q: Episode title (URL encoded)
- channelId: Specific channel ID to search within
- type:
video - Only searches for videos
- maxResults:
1 - Returns only the best match
The search is limited to the official Nadie Sabe Nada YouTube channel to ensure you get the correct video.
Video Player Component
The YouTube player is embedded using the react-youtube library:
{youtubeVideoId && (
<motion.div
className={styles.youtubePlayer}
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ delay: 0.4, duration: 0.5 }}
>
<YouTube
videoId={youtubeVideoId}
opts={{
height: "390",
width: "640",
playerVars: {
autoplay: 0
},
modestbranding: 1,
showinfo: 0
}}
className={styles.youtubePlayer}
onPlay={() => dispatch(togglePlay(false))}
/>
</motion.div>
)}
Player Configuration
The YouTube player is configured with these options:
| Option | Value | Purpose |
|---|
| height | 390 | Player height in pixels |
| width | 640 | Player width in pixels |
| autoplay | 0 | Prevents auto-play on load |
| modestbranding | 1 | Minimizes YouTube branding |
| showinfo | 0 | Hides video information |
The player automatically pauses the audio player when you start the YouTube video, preventing audio overlap.
Audio/Video Coordination
Automatic Audio Pause
When you play the YouTube video, the audio player automatically pauses:
<YouTube
videoId={youtubeVideoId}
opts={{...}}
onPlay={() => dispatch(togglePlay(false))}
/>
This prevents both audio and video from playing simultaneously.
Starting the YouTube video will pause your audio playback. Your audio position is saved, so you can resume later.
Animations
The YouTube player appears with a smooth fade and scale animation:
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ delay: 0.4, duration: 0.5 }}
Animation Sequence
Page Loads
Episode detail page begins rendering
Title Appears
Episode title fades in (0.2s delay)
Video Loads
YouTube player fades in and scales up (0.4s delay)
Content Follows
Description and metadata appear (0.6s+ delays)
Environment Configuration
The YouTube integration requires environment variables:
const YT_API_KEY = process.env.REACT_APP_YT_API_KEY;
const CHANNEL_ID = process.env.REACT_APP_CHANNEL_ID;
Required Environment Variables
Add these to your .env file:
REACT_APP_YT_API_KEY=your_youtube_api_key_here
REACT_APP_CHANNEL_ID=channel_id_here
You need a YouTube Data API v3 key to enable video discovery. Get one from the Google Cloud Console.
Getting a YouTube API Key
Create Project
Create a new project or select an existing one
Enable YouTube API
Enable the YouTube Data API v3
Create Credentials
Create an API key in the Credentials section
Add to Environment
Add the API key to your .env file
Error Handling
The integration includes error handling for failed API requests:
try {
const response = await fetch(...);
const data = await response.json();
if (data.items && data.items.length > 0) {
setYoutubeVideoId(data.items[0].id.videoId);
}
} catch (error) {
console.error("Error fetching YouTube video:", error);
}
Fallback Behavior
When video discovery fails:
- No error message is shown to the user
- The page continues to function normally
- Audio player remains fully functional
- Only the video player is omitted
If a video cannot be found, the episode detail page still displays all other information and the audio player works normally.
Responsive Design
The YouTube player is responsive and adapts to different screen sizes through CSS:
.youtubePlayer {
position: relative;
width: 100%;
max-width: 640px;
margin: 0 auto;
}
.youtubePlayer iframe {
width: 100%;
height: auto;
aspect-ratio: 16/9;
}
Best Practices
For optimal YouTube integration:
- Set up API quotas appropriately in Google Cloud Console
- Monitor your API usage to avoid hitting quota limits
- Consider caching video IDs if you hit quota limits
- The channel ID should be specific to avoid wrong video matches
Limitations
Current Limitations:
- Only searches the specified channel (prevents mismatches)
- Returns only the first search result
- Requires active internet connection
- Subject to YouTube API quota limits
- No video caching (fetches on every page load)
Future Enhancements
Potential improvements to the YouTube integration:
- Cache video IDs in localStorage to reduce API calls
- Add fallback search if primary search fails
- Support for multiple video sources
- Video quality selection
- Picture-in-picture mode
- Synchronized playback between audio and video
Usage Example
Navigate to Episode
Click any episode card from the main page
View Video
The YouTube video player appears automatically below the title
Play Video
Click play on the YouTube player to watch the video version
Switch to Audio
Use the audio player controls to switch back to audio-only
YouTube integration provides the best of both worlds - watch the video version or just listen to the audio, all from the same page.