fix(docs): youtube iframe lack titles (#50225)

## What kind of change does this PR introduce?

a11y bug fix on youtube embed

## What is the current behavior?

YouTube iframes across guide pages have no `title` attribute, so screen
readers announce them as an unnamed frame

## What is the new behavior?

- extracts a `YouTube.tsx` ui component
- adds `<YouTube id title />` + `title` as a required prop

## Test
1. visit `/docs/guides/ai/examples/openai`


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Documentation**
- Standardized embedded YouTube videos across guides with a consistent
video player.
  - Added descriptive titles to improve accessibility and clarity.
  - Preserved existing video content and playback behavior.
- Updated video embeds across AI, authentication, database, functions,
realtime, self-hosting, storage, and migration documentation.
- **New Features**
- Added privacy-enhanced YouTube playback for embedded documentation
videos.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Anthony Lio authored and GitHub committed 2026-09-11 23:37:52 +03:00
1 parent 66e6cd1639
commit 71d652483e
31 files changed
+56 -272

No files matched your search

@@ -551,11 +551,4 @@ Want to learn more about the awesome tech that is powering this?
- Read the pgvector Docs for [Embeddings and vector similarity](/docs/guides/database/extensions/pgvector)
- Watch Greg's video for a full breakdown:
<div class="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/Yhtjd7yGGGA"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="Yhtjd7yGGGA" title="Vector search with Next.js and OpenAI" />
@@ -102,11 +102,4 @@ supabase secrets set --env-file ./supabase/.env.local
If you're interesting in learning how to use this to build your own ChatGPT, read [the blog post](/blog/chatgpt-supabase-docs) and check out the video:
<div class="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/Yhtjd7yGGGA"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="Yhtjd7yGGGA" title="Building vector search with OpenAI embeddings" />
@@ -565,14 +565,7 @@ Future<void> _nativeGoogleSignIn() async {
...
```
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/utMg6fVmX0U"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="utMg6fVmX0U" title="Google One Tap sign-in with Next.js" />
</TabPanel>
@@ -593,14 +586,7 @@ await supabase.auth.signInWithOAuth(
This call takes the user to Google's consent screen. Once the flow ends, the user's profile information is exchanged and validated with Supabase Auth before it redirects back to your Flutter application with an access and refresh token representing the user's session.
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/utMg6fVmX0U"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="utMg6fVmX0U" title="Google sign-in with Flutter on web and desktop" />
</TabPanel>
@@ -755,14 +741,7 @@ Button(onClick = { authState.startFlow() }) {
}
```
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/P_jZMDmodG4"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="P_jZMDmodG4" title="Google sign-in with Kotlin Multiplatform" />
</TabPanel>
@@ -9,14 +9,7 @@ The `http` extension allows you to call RESTful endpoints within Postgres.
## Quick demo
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/rARgrELRCwY"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="rARgrELRCwY" title="Calling an external API with the http extension" />
## Overview
@@ -10,14 +10,7 @@ These functions live inside your database, and they can be [used with the API](.
## Quick demo
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/MJZCCpCYEqk"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="MJZCCpCYEqk" title="Creating and calling Postgres functions" />
## Getting started
@@ -657,33 +650,12 @@ select advanced_example();
### Create Database Functions
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/MJZCCpCYEqk"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="MJZCCpCYEqk" title="Creating a Postgres function in the dashboard" />
### Call Database Functions using JavaScript
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/I6nnp9AINJk"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="I6nnp9AINJk" title="Calling a Postgres function from JavaScript" />
### Using Database Functions to call an external API
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/rARgrELRCwY"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="rARgrELRCwY" title="Calling an external API from a Postgres function" />
+1 -8
View File
@@ -423,14 +423,7 @@ For example if you had the following situations:
>
<TabPanel id="dashboard" label="Dashboard">
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/TKwF3IGij5c"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="TKwF3IGij5c" title="Joining tables with foreign keys in the dashboard" />
</TabPanel>
<TabPanel id="sql" label="SQL">
+1 -9
View File
@@ -163,15 +163,7 @@ updated_at | 2022-12-14 02:51:13.938396+00
## Deep dive
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/QHLPNDrdN2w"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
</div>
<YouTube id="QHLPNDrdN2w" title="Storing secrets with Supabase Vault" />
As we mentioned, Vault stores secrets in an authenticated encrypted form. There are some details around that you may be curious about. What does authenticated mean? Where is the encryption key stored? This section explains those details.
@@ -16,14 +16,7 @@ Database Webhooks are very similar to triggers, and that's because Database Webh
This video demonstrates how you can create a new customer in Stripe each time a row is inserted into a `profiles` table:
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/codAs9-NeHM"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="codAs9-NeHM" title="Sending Database Webhooks on table changes" />
## Creating a webhook
@@ -5,14 +5,7 @@ description: 'Building a Slash Command Discord Bot with Edge Functions.'
video: 'https://www.youtube.com/v/J24Bvo_m7DM'
---
<div class="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/J24Bvo_m7DM"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="J24Bvo_m7DM" title="Building a Discord bot with Edge Functions" />
## Create an application on Discord Developer portal
@@ -5,14 +5,7 @@ description: 'Deploying Edge Functions with GitHub Actions.'
video: 'https://www.youtube.com/v/l2KlzGrhB6w'
---
<div class="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/l2KlzGrhB6w"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="l2KlzGrhB6w" title="Deploying Edge Functions with GitHub Actions" />
Use the Supabase CLI together with GitHub Actions to automatically deploy our Supabase Edge Functions. [View on GitHub](https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/github-action-deploy).
@@ -5,14 +5,7 @@ description: 'Generate Open Graph images with Deno and Supabase Edge Functions.'
video: 'https://www.youtube.com/v/jZgyOJGWayQ'
---
<div class="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/jZgyOJGWayQ"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="jZgyOJGWayQ" title="Generating OG images with Edge Functions" />
Generate Open Graph images with Deno and Supabase Edge Functions. [View on GitHub](https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/opengraph).
@@ -286,14 +286,7 @@ Push notifications are an important part of any mobile app. They allow you to se
1. In your `notifications` table, insert a new row.
1. Watch the magic happen 🪄
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/CiSv9E6ZKVc"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="CiSv9E6ZKVc" title="Sending push notifications from Edge Functions" />
</TabPanel>
</Tabs>
@@ -3,14 +3,7 @@ title: 'Rate Limiting Edge Functions'
description: 'Rate Limiting Edge Functions with Upstash Redis.'
---
<div class="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/o4ooiE-SdUg"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="o4ooiE-SdUg" title="Rate limiting Edge Functions with Upstash Redis" />
[Redis](https://redis.io/about/) is an open source (BSD licensed), in-memory data structure store used as a database, cache, message broker, and streaming engine. It is optimized for atomic operations like incrementing a value, for example for a view counter or rate limiting. We can even rate limit based on the user ID from Supabase Auth!
@@ -3,14 +3,7 @@ title: 'Taking Screenshots with Puppeteer'
description: 'Take screenshots in Edge Functions with Puppeteer and Browserless.io.'
---
<div class="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/Q1nfnQggR4c"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="Q1nfnQggR4c" title="Taking screenshots with Puppeteer and Edge Functions" />
[Puppeteer](https://pptr.dev/) is a handy tool to programmatically take screenshots and generate PDFs. However, trying to do so in Edge Functions can be challenging due to the size restrictions. Luckily there is a [serverless browser offering available](https://www.browserless.io/) that we can connect to via WebSockets.
@@ -3,14 +3,7 @@ title: 'Handling Stripe Webhooks'
description: 'Handling signed Stripe Webhooks with Edge Functions.'
---
<div class="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/6OMVWiiycLs"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="6OMVWiiycLs" title="Handling signed Stripe webhooks with Edge Functions" />
Handling signed Stripe Webhooks with Edge Functions. [View on GitHub](https://github.com/supabase/supabase/blob/master/examples/edge-functions/supabase/functions/stripe-webhooks/index.ts).
@@ -5,13 +5,6 @@ description: 'Building a Telegram Bot with Edge Functions.'
video: 'https://www.youtube.com/v/AWfE3a9J_uo'
---
<div class="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/AWfE3a9J_uo"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="AWfE3a9J_uo" title="Building a Telegram bot with Edge Functions" />
Handle Telegram Bot Webhooks with the [grammY framework](https://grammy.dev/). grammY is an open source Telegram Bot Framework which makes it easy to handle and respond to incoming messages. [View on GitHub](https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/telegram-bot).
@@ -3,14 +3,7 @@ title: 'Upstash Redis'
description: 'Build an Edge Functions Counter with Upstash Redis.'
---
<div class="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/OPg3_oPZCh0"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="OPg3_oPZCh0" title="Using Upstash Redis with Edge Functions" />
A Redis counter example that stores a [hash](https://redis.io/commands/hincrby/) of function invocation count per region. Find the code on [GitHub](https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/upstash-redis-counter).
@@ -4,14 +4,7 @@ title: 'Type-Safe SQL with Kysely'
description: 'Combining Kysely with Deno Postgres gives you a convenient developer experience for interacting directly with your Postgres database.'
---
<div class="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/zd9a_Lk3jAc"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="zd9a_Lk3jAc" title="Type-safe SQL in Edge Functions with Kysely" />
Supabase Edge Functions can [connect directly to your Postgres database](/docs/guides/functions/connect-to-postgres) to execute SQL queries. [Kysely](https://github.com/kysely-org/kysely#kysely) is a type-safe and autocompletion-friendly typescript SQL query builder.
@@ -4,14 +4,7 @@ title: 'Scheduling Edge Functions'
description: 'Schedule Edge Functions with pg_cron.'
---
<div class="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/-U6DJcjVvGo"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="-U6DJcjVvGo" title="Scheduling Edge Functions with pg_cron" />
The hosted Supabase Platform supports the [`pg_cron` extension](/docs/guides/database/extensions/pg_cron), a recurring job scheduler in Postgres.
@@ -23,14 +23,7 @@ This page is a focused tutorial on migrations. If you want to move an existing p
Database changes are managed through "migrations." Database migrations are a common way of tracking changes to your database over time.
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/Kx5nHBmIxyQ"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="Kx5nHBmIxyQ" title="Managing database migrations with the Supabase CLI" />
For this guide, we'll create a table called `employees` and see how we can make changes to it.
@@ -12,14 +12,7 @@ Alternatively, use the [Heroku to Supabase migration tool](https://migrate.supab
## Quick demo
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/xsRhPMphtZ4"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="xsRhPMphtZ4" title="Migrating a Heroku Postgres database to Supabase" />
## Retrieve your Heroku database credentials [#retrieve-heroku-credentials]
@@ -7,11 +7,4 @@ sidebar_label: 'Videos'
The Postgres Changes extension listens for database changes and sends them to clients which enables you to receive database changes in real-time.
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/gboTC2lcgzw?si=WBfCrZyqi9zDWS5n"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="gboTC2lcgzw" title="Listening to Postgres changes with Flutter" />
@@ -9,11 +9,4 @@ Use Supabase Presence to display the currently online users on your Flutter appl
Displaying the list of currently online users is a common feature for real-time collaborative applications. Supabase Presence makes it easy to track users joining and leaving the session so that you can make a collaborative app.
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/B2NZvZ2uLNs?si=2JmxGOFuwwUGaTxr"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="B2NZvZ2uLNs" title="Using Realtime Presence with Flutter" />
@@ -8,11 +8,4 @@ sidebar_label: 'Videos'
In this guide, we explore the best ways to receive real-time Postgres changes with your Next.js application.
We'll show both client and server side updates, and explore which option is best.
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/YR-xP6PPXXA"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="YR-xP6PPXXA" title="Building a Realtime app with Next.js" />
@@ -93,13 +93,7 @@ const changes = supabase
Postgres Changes require minimal setup, but have some [limitations](/docs/guides/realtime/postgres-changes#limitations) as your application scales. We recommend using Broadcast for most use cases.
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/2rUjcmgZDwQ"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="2rUjcmgZDwQ" title="Subscribing to Postgres changes with Realtime" />
### Enable Postgres Changes
@@ -609,14 +609,7 @@ Some suggested systems include:
## Demo
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/FqiQKRKsfZE"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="FqiQKRKsfZE" title="Self-hosting Supabase on a DigitalOcean droplet" />
1. The VPS instance is a DigitalOcean droplet. (For server requirements refer to [System requirements](#system-requirements))
2. To access Studio, use the IPv4 IP address of your Droplet.
@@ -314,11 +314,4 @@ create policy "Public Access"
{/* Finish with a video. This also appears in the Sidebar via the "tocVideo" metadata */}
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/J9mTPY8rIXE"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="J9mTPY8rIXE" title="Adding security rules to Supabase Storage" />
@@ -102,14 +102,7 @@ create policy "Avatar images are publicly accessible." on storage.objects
{/* Finish with a video. This also appears in the Sidebar via the "tocVideo" metadata */}
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/4ERX__Y908k"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="4ERX__Y908k" title="Storage access control policy examples" />
## Bypassing access controls
@@ -801,11 +801,4 @@ IMGPROXY_URL=yourinternalimgproxyurl.internal.com
{/* Finish with a video. This also appears in the Sidebar via the "tocVideo" metadata */}
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/dLqSmxX3r7I"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<YouTube id="dLqSmxX3r7I" title="Configuring the Storage image transformation API" />
@@ -30,6 +30,7 @@ import { Accordion, AccordionItem } from '~/features/ui/Accordion'
import { CodeBlock } from '~/features/ui/CodeBlock/CodeBlock'
import { ShowUntil } from '~/features/ui/ShowUntil'
import { TabPanel, Tabs } from '~/features/ui/Tabs'
import { YouTube } from '~/features/ui/YouTube'
import { ArrowDown, Check, X } from 'lucide-react'
import Link from 'next/link'
import { type ComponentPropsWithoutRef } from 'react'
@@ -115,6 +116,7 @@ const components = {
TabPanel,
TerraformProviderSchema,
WrapperDashboardIntegration,
YouTube,
a: MdxAnchor,
h2: (props: ComponentPropsWithoutRef<'h2'>) => (
<Heading tag="h2" {...props}>
+20
View File
@@ -0,0 +1,20 @@
import { cn } from 'ui'
export const YouTube = ({
id,
title,
className,
}: {
id: string
title: string
className?: string
}) => (
<div className={cn('video-container', className)}>
<iframe
src={`https://www.youtube-nocookie.com/embed/${id}`}
title={`Youtube video: ${title}`}
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
/>
</div>
)