Last updated: July 2026 — now covers Shorts and /live/ URLs
The video ID is the 11-character code YouTube uses everywhere, but it hides in half a dozen URL shapes:
https://www.youtube.com/watch?v=dQw4w9WgXcQ
https://www.youtube.com/watch?v=dQw4w9WgXcQ&list=PLx...
One regex for all of them
(?:youtube\.com/(?:watch\?(?:.*&)?v=|embed/|shorts/|live/)|youtu\.be/)([A-Za-z0-9_-]{11})
PHP
function youtube_video_id(string $url): ?string
{
$pattern = '~(?:youtube\.com/(?:watch\?(?:.*&)?v=|embed/|shorts/|live/)|youtu\.be/)([A-Za-z0-9_-]{11})~';
return preg_match($pattern, $url, $m) ? $m[1] : null;
}
youtube_video_id('https://www.youtube.com/shorts/dQw4w9WgXcQ'); // "dQw4w9WgXcQ"
Prefer a non-regex approach? For classic watch URLs, parse_url() + parse_str() on the query string gives you v directly — but you’ll still need the regex for youtu.be, Shorts, and embeds, so in practice the single regex is simpler.
JavaScript
function youtubeVideoId(url) {
const m = url.match(
/(?:youtube\.com\/(?:watch\?(?:.*&)?v=|embed\/|shorts\/|live\/)|youtu\.be\/)([A-Za-z0-9_-]{11})/
);
return m ? m[1] : null;
}
What to do with the ID
Embed it:
<iframe src="https://www.youtube.com/embed/VIDEO_ID" allowfullscreen></iframe>
Or grab its thumbnail in any size — every format is listed in my guide to YouTube thumbnail URLs.
Edge cases to know: IDs are exactly 11 characters of A–Z a–z 0–9 _ -; the {11} quantifier keeps playlist IDs (which are longer) from matching, and the (?:.*&)? handles URLs where v= isn’t the first query parameter.
