mirror of
https://github.com/svemagie/indiekit-endpoint-youtube.git
synced 2026-04-02 15:54:59 +02:00
Features: - Display latest videos from any YouTube channel - Live streaming status with animated badge - Upcoming stream detection - Admin dashboard with video grid - Public JSON API for Eleventy integration - Quota-efficient API usage (playlist method) - Smart caching (5min videos, 1min live status) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
136 lines
3.3 KiB
Plaintext
136 lines
3.3 KiB
Plaintext
{#
|
|
YouTube Widget - Embeddable component showing latest video and live status
|
|
|
|
Usage in your templates:
|
|
{% include "@indiekit-endpoint-youtube-widget.njk" %}
|
|
|
|
Requires youtube data to be fetched and passed to the template context
|
|
#}
|
|
|
|
<style>
|
|
.youtube-widget {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.75rem;
|
|
padding: 1rem;
|
|
background: var(--color-offset, #f5f5f5);
|
|
border-radius: 0.5rem;
|
|
}
|
|
.youtube-widget__header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
.youtube-widget__title {
|
|
font-weight: 600;
|
|
font-size: 0.875rem;
|
|
margin: 0;
|
|
}
|
|
.youtube-widget__live {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.375rem;
|
|
padding: 0.125rem 0.5rem;
|
|
border-radius: 1rem;
|
|
font-size: 0.625rem;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
}
|
|
.youtube-widget__live--on {
|
|
background: #ff0000;
|
|
color: white;
|
|
}
|
|
.youtube-widget__live--off {
|
|
background: #e5e5e5;
|
|
color: #666;
|
|
}
|
|
.youtube-widget__live-dot {
|
|
width: 6px;
|
|
height: 6px;
|
|
border-radius: 50%;
|
|
background: currentColor;
|
|
}
|
|
.youtube-widget__video {
|
|
display: flex;
|
|
gap: 0.75rem;
|
|
}
|
|
.youtube-widget__thumb {
|
|
width: 120px;
|
|
height: 68px;
|
|
object-fit: cover;
|
|
border-radius: 0.25rem;
|
|
flex-shrink: 0;
|
|
}
|
|
.youtube-widget__info {
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
.youtube-widget__video-title {
|
|
font-size: 0.875rem;
|
|
font-weight: 500;
|
|
margin: 0 0 0.25rem 0;
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 2;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
}
|
|
.youtube-widget__video-title a {
|
|
color: inherit;
|
|
text-decoration: none;
|
|
}
|
|
.youtube-widget__video-title a:hover {
|
|
text-decoration: underline;
|
|
}
|
|
.youtube-widget__meta {
|
|
font-size: 0.75rem;
|
|
color: var(--color-text-secondary, #666);
|
|
}
|
|
</style>
|
|
|
|
<div class="youtube-widget">
|
|
<div class="youtube-widget__header">
|
|
<h3 class="youtube-widget__title">YouTube</h3>
|
|
{% if youtube.isLive %}
|
|
<span class="youtube-widget__live youtube-widget__live--on">
|
|
<span class="youtube-widget__live-dot"></span>
|
|
Live
|
|
</span>
|
|
{% else %}
|
|
<span class="youtube-widget__live youtube-widget__live--off">
|
|
Offline
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if youtube.liveStream %}
|
|
<div class="youtube-widget__video">
|
|
<img src="{{ youtube.liveStream.thumbnail }}" alt="" class="youtube-widget__thumb">
|
|
<div class="youtube-widget__info">
|
|
<h4 class="youtube-widget__video-title">
|
|
<a href="{{ youtube.liveStream.url }}" target="_blank" rel="noopener">
|
|
{{ youtube.liveStream.title }}
|
|
</a>
|
|
</h4>
|
|
<p class="youtube-widget__meta">🔴 Streaming now</p>
|
|
</div>
|
|
</div>
|
|
{% elif youtube.videos and youtube.videos[0] %}
|
|
{% set video = youtube.videos[0] %}
|
|
<div class="youtube-widget__video">
|
|
<img src="{{ video.thumbnail }}" alt="" class="youtube-widget__thumb">
|
|
<div class="youtube-widget__info">
|
|
<h4 class="youtube-widget__video-title">
|
|
<a href="{{ video.url }}" target="_blank" rel="noopener">
|
|
{{ video.title }}
|
|
</a>
|
|
</h4>
|
|
<p class="youtube-widget__meta">
|
|
{{ video.viewCount | localeNumber }} views
|
|
</p>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<p class="youtube-widget__meta">No videos available</p>
|
|
{% endif %}
|
|
</div>
|