Skip to content

Instantly share code, notes, and snippets.

@thenetaji
Last active December 22, 2025 08:03
Show Gist options
  • Select an option

  • Save thenetaji/538d5669ac3bc0498fba04813e8e2378 to your computer and use it in GitHub Desktop.

Select an option

Save thenetaji/538d5669ac3bc0498fba04813e8e2378 to your computer and use it in GitHub Desktop.
A robust utility function to reliably extract the 11-character YouTube video ID from all official URL formats

A robust utility function to reliably extract the 11-character YouTube video ID from all official URL formats. Most solutions break on edge cases, but this logic handles variations including shorts, live streams, and mobile URLs.

Supported URL Formats

The extractor supports the following formats, including those with extra parameters (like ?t= or &si=):

  • Standard: youtube.com/watch?v=VIDEO_ID
  • Shortened: youtu.be/VIDEO_ID
  • Shorts: youtube.com/shorts/VIDEO_ID
  • Embeds: youtube.com/embed/VIDEO_ID
  • Legacy/Alternative: youtube.com/v/VIDEO_ID or /e/VIDEO_ID
  • Live: youtube.com/live/VIDEO_ID
  • Privacy Enhanced: youtube-nocookie.com/embed/VIDEO_ID
  • Subdomains: m.youtube.com, music.youtube.com

Implementation (JavaScript / TypeScript)

/**
 * Extracts the 11-character YouTube video ID from a URL string.
 * @param {string} input - The YouTube URL.
 * @returns {string|null} - The video ID or null if invalid.
 */
function extractYouTubeVideoId(input) {
  if (!input) return null;

  const urlString = input.startsWith("http")
    ? input
    : `https://${input}`;

  let url;
  try {
    url = new URL(urlString);
  } catch {
    return null;
  }

  const host = url.hostname.toLowerCase();
  let id = null;

  // Handle shortened youtu.be links
  if (host === "youtu.be") {
    id = url.pathname.split("/")[1];
  } 
  // Handle standard and nocookie domains
  else if (
    host.endsWith("youtube.com") ||
    host.endsWith("youtube-nocookie.com")
  ) {
    const parts = url.pathname.split("/");

    // Path-based IDs: /shorts/, /live/, /embed/, etc.
    if (["embed", "v", "e", "shorts", "live"].includes(parts[1])) {
      id = parts[2];
    }

    // Query-based IDs: ?v=
    if (!id) {
      id = url.searchParams.get("v");
    }
  }

  // Validate the ID is exactly 11 characters and uses valid characters
  return id && /^[a-zA-Z0-9_-]{11}$/.test(id) ? id : null;
}

Enjoy! - 22/12/2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment