Skip to content

Commit e263e99

Browse files
committed
Release v0.1.0
Breaking changes: - Changed the export from `default` to a named `YouTube` export - Renamed the `videoCode` prop to `videoId` to match what YouTube uses in their docs New: - Added an `embedParams` prop to expose all the settings from the [YouTube Iframe Player API](https://developers.google.com/youtube/player_parameters#Parameters) - Default settings are {autoplay: 1, modestbranding: 1} - Added a `thumbNailRes` prop to let you choose the thumbnail size/quality which is used - Default setting is 'standard' (which is bigger than 'high' - go figure) - Not all videos have all thumbnail sizes (especially older ones), so you may have to tweak this on a per-video basis
1 parent cfd09d4 commit e263e99

7 files changed

+108
-38
lines changed

README.md

+24-9
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,38 @@ Lazily embed YouTube videos with a [static placeholder using the `<iframe>` `src
88
npm i astro-lazy-youtube-embed
99
```
1010

11-
## Example
11+
## Usage
1212

13-
This component uses a `default` export, so you can import it as whichever name you prefer:
13+
Use `embedParams` to pass [YouTube IFrame Player API parameters](https://developers.google.com/youtube/player_parameters#Parameters) for the embed, e.g. to set start & stop times to play a particular section when clicked.
14+
15+
Use `thumbnailRes` to control the resolution of the thumbnail used for the placeholder.
1416

1517
```astro
1618
---
17-
import YouTubeVideo from 'astro-lazy-youtube-embed'
19+
import {YouTube} from 'astro-lazy-youtube-embed'
1820
---
19-
<YouTubeVideo videoCode="FfTT7mxGw8I" title="Just Curious - Limmy's Homemade Show"/>
21+
<YouTube
22+
title="Just Curious - Limmy's Homemade Show"
23+
videoId="FfTT7mxGw8I"
24+
/>
25+
26+
<div class="my-8">Configure the embed features and thumbnail size:</div>
27+
28+
<YouTube
29+
embedParams={{start: 19, end: 22}}
30+
thumbnailRes="maxres"
31+
title="Frimmerang"
32+
videoId="xptCWoB_VCE"
33+
/>
2034
21-
<div class="my-8">Provide your own class for additional styling:</div>
35+
<div class="my-8">Pass other HTML attributes for the <code>&lt;iframe&gt;</code>:</div>
2236
23-
<YouTubeVideo
24-
class="rounded"
25-
videoCode="L0C5nyOVTzc"
37+
<YouTube
38+
class="rounded-2xl"
39+
id="techno"
2640
title="Limmy Teaches Techno - Limmy's Homemade Show"
41+
videoId="L0C5nyOVTzc"
2742
/>
2843
```
2944

30-
![Rendered version of the above example code](/example.jpg)
45+
![Rendered version of the above example code](./example.jpg)

YouTube.astro

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
---
2+
interface Props extends astroHTML.JSX.HTMLAttributes {
3+
embedParams?: EmbedParams
4+
thumbnailRes?: ThumbnailRes
5+
title: string
6+
videoId: string
7+
}
8+
9+
interface EmbedParams {
10+
autoplay?: ToggleParam
11+
cc_lang_pref?: string
12+
cc_load_policy?: ToggleParam
13+
color?: 'red' | 'white'
14+
controls?: ToggleParam
15+
disablekb?: ToggleParam
16+
enablejsapi?: ToggleParam
17+
end?: number
18+
fs?: ToggleParam
19+
hl?: string
20+
iv_load_policy?: 1 | '1' | 3 | '3'
21+
list?: string
22+
listType?: 'playlist' | 'user_uploads'
23+
loop?: ToggleParam
24+
modestbranding?: ToggleParam
25+
origin?: string
26+
playlist?: string
27+
playslinline?: ToggleParam
28+
rel?: ToggleParam
29+
start?: number
30+
widget_referrer?: string
31+
}
32+
33+
type ToggleParam = 0 | '0' | 1 | '1'
34+
35+
type ThumbnailRes = 120 | '120' | 'default' | 320 | '320' | 'medium' | 480 | '480' | 'high' | 640 | '640' | 'standard' | 1280 | '1280' | 'maxres'
36+
37+
const QUALITY_PREFIXES = {
38+
120: '',
39+
default: '',
40+
320: 'mq',
41+
medium: 'mq',
42+
480: 'hq',
43+
high: 'hq',
44+
640: 'sd',
45+
standard: 'sd',
46+
1280: 'maxres',
47+
maxres: 'maxres',
48+
}
49+
50+
let {
51+
embedParams,
52+
thumbnailRes = 'standard',
53+
title,
54+
videoId,
55+
...attrs
56+
} = Astro.props as Props
57+
58+
let params: EmbedParams = {...{autoplay: 1, modestbranding: 1}, ...embedParams}
59+
60+
let thumbnailUrl = `https://img.youtube.com/vi/${videoId}/${QUALITY_PREFIXES[thumbnailRes]}default.jpg`
61+
let embedQuery = Object.keys(params).map(key => `${key}=${params[key]}`).join('&')
62+
let embedUrl = `https://www.youtube.com/embed${videoId ? `/${videoId}` : ''}${embedQuery ? `?${embedQuery}` : ''}`
63+
let playButtonSvg = `<svg height="100%" version="1.1" viewBox="0 0 68 48" width="100%"><path d="M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z" fill="#f00"></path><path d="M 45,24 27,14 27,34" fill="#fff"></path></svg>`
64+
let gradientStyle = `.gradient{width:100%;height:49px;padding-bottom:50px;position:absolute;top:0;background-repeat:repeat-x;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAADGCAYAAAAT+OqFAAAAdklEQVQoz42QQQ7AIAgEF/T/D+kbq/RWAlnQyyazA4aoAB4FsBSA/bFjuF1EOL7VbrIrBuusmrt4ZZORfb6ehbWdnRHEIiITaEUKa5EJqUakRSaEYBJSCY2dEstQY7AuxahwXFrvZmWl2rh4JZ07z9dLtesfNj5q0FU3A5ObbwAAAABJRU5ErkJggg==);pointer-events:none;}`
65+
let style = `<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img{position:absolute;width:100%;top:0;bottom:0;margin:auto}.button{position:absolute;left:50%;top:50%;width:68px;height:48px;margin-left:-34px;margin-top:-24px;}.top{position:absolute;top:18px;left:18px;right:18px;display:flex;flex-wrap:nowrap}.title{color:#fff;font-size:18px;white-space:nowrap;word-wrap:normal;text-shadow:0 0 2px rgba(0,0,0,.5);font-family:"YouTube Noto",Roboto,Arial,Helvetica,sans-serif;line-height:1.3;text-overflow:ellipsis;overflow:hidden;}${gradientStyle}</style>`
66+
let srcdoc = `${style}<a href="${embedUrl}"><img src="${thumbnailUrl}" alt="${title}"><div class="gradient"></div><div class="top"><div class="title">${title}</div></div><div class="button">${playButtonSvg}</div></a>`
67+
---
68+
<iframe
69+
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
70+
allowfullscreen
71+
frameborder="0"
72+
style="width: 100%; aspect-ratio: 16/9;"
73+
{...attrs}
74+
src={embedUrl}
75+
srcdoc={srcdoc}
76+
title={title}
77+
/>

YouTubeVideo.astro

-22
This file was deleted.

example.jpg

39.9 KB
Loading

index.js

-1
This file was deleted.

index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {default as YouTube} from './YouTube.astro'

package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
{
22
"name": "astro-lazy-youtube-embed",
3-
"version": "0.0.2",
3+
"version": "0.1.0",
44
"description": "Embed YouTube videos with a static placeholder which only embeds when you click",
55
"type": "module",
66
"license": "MIT",
77
"author": "Jonny Buchanan <[email protected]>",
88
"exports": {
9-
".": "./index.js"
9+
".": "./index.ts"
1010
},
1111
"files": [
12-
"index.js",
12+
"index.ts",
1313
"LICENSE",
14-
"YouTubeVideo.astro"
14+
"YouTube.astro"
1515
],
1616
"keywords": [
1717
"astro",
1818
"astro-component",
19-
"lazy",
2019
"youtube",
21-
"embed"
20+
"embeds",
21+
"lazy"
2222
],
2323
"peerDependencies": {
2424
"astro": "^1.0.0 || ^2.0.0-beta"

0 commit comments

Comments
 (0)