A YouTube video embedding extension for the Tiptap rich text editor framework
npx @tessl/cli install tessl/npm-tiptap--extension-youtube@3.4.1A YouTube video embedding extension for the Tiptap rich text editor framework. Built as a ProseMirror node extension, it enables developers to seamlessly embed YouTube videos within rich text documents with comprehensive configuration options including autoplay controls, caption settings, keyboard navigation, fullscreen capabilities, and custom styling parameters.
npm install @tiptap/extension-youtubeimport { Youtube } from "@tiptap/extension-youtube";For default import:
import Youtube from "@tiptap/extension-youtube";CommonJS:
const { Youtube } = require("@tiptap/extension-youtube");import { Editor } from '@tiptap/core';
import { Youtube } from '@tiptap/extension-youtube';
const editor = new Editor({
extensions: [
Youtube.configure({
width: 480,
height: 320,
nocookie: true, // Use youtube-nocookie.com for privacy
}),
],
});
// Insert a YouTube video
editor.commands.setYoutubeVideo({
src: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
width: 640,
height: 480,
});The extension is built around several key components:
Youtube node extending Tiptap's Node class for rich text integrationThe main extension for embedding YouTube videos in Tiptap editors.
/**
* YouTube video embedding extension for Tiptap
*/
const Youtube: Node<YoutubeOptions>;
interface YoutubeOptions {
/** Controls if the paste handler for youtube videos should be added */
addPasteHandler: boolean;
/** Controls if the youtube video should be allowed to go fullscreen */
allowFullscreen: boolean;
/** Controls if the youtube video should autoplay */
autoplay: boolean;
/** The language of the captions shown in the youtube video */
ccLanguage?: string;
/** Controls if the captions should be shown in the youtube video */
ccLoadPolicy?: boolean;
/** Controls if the controls should be shown in the youtube video */
controls: boolean;
/** Controls if the keyboard controls should be disabled in the youtube video */
disableKBcontrols: boolean;
/** Controls if the iframe api should be enabled in the youtube video */
enableIFrameApi: boolean;
/** The end time of the youtube video in seconds */
endTime: number;
/** The height of the youtube video in pixels */
height: number;
/** The language of the youtube video interface */
interfaceLanguage?: string;
/** Controls if the video annotations should be shown in the youtube video */
ivLoadPolicy: number;
/** Controls if the youtube video should loop */
loop: boolean;
/** Controls if the youtube video should show a small youtube logo */
modestBranding: boolean;
/** The HTML attributes for a youtube video node */
HTMLAttributes: Record<string, any>;
/** Controls if the youtube node should be inline or not */
inline: boolean;
/** Controls if the youtube video should be loaded from youtube-nocookie.com */
nocookie: boolean;
/** The origin of the youtube video for API calls */
origin: string;
/** The playlist of the youtube video */
playlist: string;
/** The color of the youtube video progress bar */
progressBarColor?: string;
/** The width of the youtube video in pixels */
width: number;
/** Controls if the related youtube videos at the end are from the same channel */
rel: number;
}Usage Examples:
import { Editor } from '@tiptap/core';
import { Youtube } from '@tiptap/extension-youtube';
// Basic configuration
const editor = new Editor({
extensions: [
Youtube.configure({
width: 640,
height: 480,
nocookie: true,
}),
],
});
// Advanced configuration with privacy and accessibility features
const editor = new Editor({
extensions: [
Youtube.configure({
width: 800,
height: 450,
autoplay: false,
controls: true,
disableKBcontrols: false,
allowFullscreen: true,
nocookie: true, // GDPR-friendly
modestBranding: true,
ccLanguage: 'en',
ccLoadPolicy: true,
progressBarColor: 'red',
rel: 0, // Don't show related videos from other channels
}),
],
});Commands for programmatically inserting YouTube videos.
/**
* Insert a YouTube video into the editor
* @param options Video configuration options
* @returns Command that returns boolean indicating success/failure
*/
setYoutubeVideo(options: {
/** YouTube video URL (required) */
src: string;
/** Video width in pixels (optional) */
width?: number;
/** Video height in pixels (optional) */
height?: number;
/** Start time in seconds (optional) */
start?: number;
}): boolean;Usage Examples:
// Insert a video with basic options
const success = editor.commands.setYoutubeVideo({
src: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
});
// Insert a video with custom dimensions and start time
const result = editor.commands.setYoutubeVideo({
src: 'https://youtu.be/dQw4w9WgXcQ',
width: 800,
height: 450,
start: 30, // Start at 30 seconds
});
// Insert a video from various YouTube URL formats
const inserted = editor.commands.setYoutubeVideo({
src: 'https://youtube-nocookie.com/watch?v=dQw4w9WgXcQ',
});The extension supports various YouTube URL formats:
https://www.youtube.com/watch?v=VIDEO_IDhttps://youtu.be/VIDEO_IDhttps://youtube-nocookie.com/watch?v=VIDEO_IDhttps://m.youtube.com/watch?v=VIDEO_IDhttps://music.youtube.com/watch?v=VIDEO_IDlist parameterThe extension handles invalid URLs gracefully:
setYoutubeVideo command returns false for invalid URLs and doesn't insert content/**
* Configuration options for the YouTube extension
*/
interface YoutubeOptions {
addPasteHandler: boolean;
allowFullscreen: boolean;
autoplay: boolean;
ccLanguage?: string;
ccLoadPolicy?: boolean;
controls: boolean;
disableKBcontrols: boolean;
enableIFrameApi: boolean;
endTime: number;
height: number;
interfaceLanguage?: string;
ivLoadPolicy: number;
loop: boolean;
modestBranding: boolean;
HTMLAttributes: Record<string, any>;
inline: boolean;
nocookie: boolean;
origin: string;
playlist: string;
progressBarColor?: string;
width: number;
rel: number;
}