Embed YouTube videos without tracking cookies
@slashclone/privacy-friendly-youtube-embed
Embed YouTube videos on your site without loading anything from Google until the visitor presses Play or allows videos. A click-to-play placeholder with a local poster swaps in the youtube-nocookie.com player, with a keyboard-friendly button, no layout shift, CSP entries, and a Playwright test that proves no YouTube request happens first. React and HTML templates. Not legal advice.
SkillDevOpsv0.1.0
- Activity
- New: be the first to try it
- Installs
- 0 installs
- Likes
- 0 likes
- Clones
- 0 clones
- 1<!doctype html>
- 2<html lang="en">
- 3 <head>
- 4 <meta charset="utf-8" />
- 5 <meta name="viewport" content="width=device-width, initial-scale=1" />
- 6 <title>Video example</title>
- 7 <style>
- 8 /* The box reserves 16:9 space before anything loads, so nothing shifts. */
- 9 .yt-embed {
- 10 position: relative;
- 11 width: 100%;
- 12 aspect-ratio: 16 / 9;
- 13 overflow: hidden;
- 14 background: #111;
- 15 color: #fff;
- 16 }
- 17 .yt-embed__fill {
- 18 position: absolute;
- 19 inset: 0;
- 20 width: 100%;
- 21 height: 100%;
- 22 border: 0;
- 23 }
- 24 .yt-embed__poster {
- 25 object-fit: cover;
- 26 opacity: 0.6;
- 27 }
- 28 .yt-embed__layer {
- 29 display: flex;
- 30 flex-direction: column;
- 31 align-items: center;
- 32 justify-content: center;
- 33 gap: 0.75rem;
- 34 padding: 1rem;
- 35 box-sizing: border-box;
- 36 text-align: center;
- 37 }
- 38 .yt-embed__title {
- 39 margin: 0;
- 40 font-weight: 600;
- 41 }
- 42 .yt-embed__title span {
- 43 font-weight: 400;
- 44 }
- 45 .yt-embed__play {
- 46 font: inherit;
- 47 padding: 0.6rem 1.2rem;
- 48 border-radius: 999px;
- 49 cursor: pointer;
- 50 }
- 51 .yt-embed__play:focus-visible,
- 52 .yt-embed__link:focus-visible,
- 53 .yt-embed a:focus-visible {
- 54 outline: 3px solid #ffd54a;
- 55 outline-offset: 3px;
- 56 }
- 57 .yt-embed__note {
- 58 margin: 0;
- 59 max-width: 32rem;
- 60 font-size: 0.8125rem;
- 61 }
- 62 .yt-embed a,
- 63 .yt-embed__link {
- 64 color: inherit;
- 65 }
- 66 .yt-embed__link {
- 67 font: inherit;
- 68 background: none;
- 69 border: 0;
- 70 padding: 0;
- 71 text-decoration: underline;
- 72 cursor: pointer;
- 73 }
- 74 </style>
- 75 </head>
- 76 <body>
- 77 <main>
- 78 <h1>Video example</h1>
- 80 <!-- data-poster must point at your own origin. Never a YouTube thumbnail URL. -->
- 81 <div
- 82 class="yt-embed"
- 83 data-video="VIDEO_ID_HERE"
- 84 data-title="Getting started in five minutes"
- 85 data-duration="5:02"
- 86 data-poster="/posters/getting-started.jpg"
- 87 data-captions="true"
- 88 ></div>
- 89 <p><a href="/transcripts/getting-started">Read the transcript</a></p>
- 90 </main>
- 92 <script src="/js/youtube-embed.js"></script>
- 93 <script>
- 94 // Wire this to your consent layer. Example: grant the embedded-media
- 95 // category from the placeholder, then listen for changes.
- 96 // YouTubeEmbeds.onAllowAll = function () { myConsent.allow("media"); };
- 97 // myConsent.onChange(function (c) { YouTubeEmbeds.setAllowed(c.media); });
- 98 YouTubeEmbeds.init();
- 99 </script>
- 100 </body>
- 101</html>
