Icons Configuration

Learn how to configure and customize all player control icons using popular icon libraries, custom SVG components, or animated icons from Framer Motion.

The video player requires a complete set of icons to power its user interface. Every button, indicator, and visual element in the player needs a corresponding icon component. This guide explains how to configure icons using various approaches, from popular icon libraries to custom animated components.

Understanding Icon Requirements

The player requires exactly fifteen distinct icons, each serving a specific purpose in the user interface. These icons are passed to the player through the icons prop as an object containing React components. The player will not function without all fifteen icons properly configured.

Here's the complete list of required icons and their purposes:

Playback Controls: The play icon appears on the main playback button when the video is paused, while the pause icon replaces it during playback. These are the most frequently interacted elements in the player.

Volume Controls: The volume icon represents normal audio state and appears on the volume control button. When audio is muted, it's replaced by the volumeMute icon, providing clear visual feedback about the audio state.

Display Modes: The fullscreen icon enables users to expand the player to fill their entire screen, while exitFullscreen appears when already in fullscreen mode to allow users to return to normal viewing. The pip icon activates Picture-in-Picture mode.

Settings and Configuration: The settings icon opens the player's configuration panel where users can adjust quality, speed, and subtitles. The speed icon appears within the settings menu to represent playback speed options. The cc icon controls closed captions and subtitle visibility.

Navigation and Selection: The back icon appears in nested settings menus, allowing users to return to the previous menu level. The check icon marks selected options in lists, such as the currently active subtitle language or playback speed.

Status Indicators: The hdChip icon appears as a badge indicating high-definition video quality. The sleepTimer icon represents the sleep timer feature that automatically pauses playback after a set duration.

All icons should be designed at 26 pixels for optimal appearance, though you can adjust this based on your design requirements.

Using Icon Libraries

Icon libraries provide pre-designed, professionally crafted icons that you can quickly integrate into your player. This approach offers consistency, saves development time, and ensures accessibility standards are met.

Lucide React

Lucide React is a modern, actively maintained icon library with excellent TypeScript support and tree-shaking capabilities. It provides clean, minimalist icons that work beautifully with the video player's design.

First, install Lucide React in your project:

npm install lucide-react

Then configure your icons by importing the specific components you need:

src/components/VideoPlayer.jsx
import { CustomVideoPlayer } from "@ntxmjs/react-custom-video-player";
import {
  Play,
  Pause,
  Volume2,
  VolumeX,
  Maximize,
  Minimize,
  PictureInPicture2,
  Settings,
  Gauge,
  Subtitles,
  ChevronLeft,
  Maximize2,
  Check,
  BadgeCheck,
  Clock,
} from "lucide-react";

function VideoPlayer() {
  const playerIcons = {
    play: <Play size={26} />,
    pause: <Pause size={26} />,
    volume: <Volume2 size={26} />,
    volumeMute: <VolumeX size={26} />,
    fullscreen: <Maximize size={26} />,
    exitFullscreen: <Minimize size={26} />,
    pip: <PictureInPicture2 size={26} />,
    settings: <Settings size={26} />,
    speed: <Gauge size={26} />,
    cc: <Subtitles size={26} />,
    back: <ChevronLeft size={26} />,
    check: <Check size={26} />,
    hdChip: <BadgeCheck size={26} />,
    sleepTimer: <Clock size={26} />,
  };

  return (
    <CustomVideoPlayer
      src="https://example.com/video.m3u8"
      poster="https://example.com/poster.jpg"
      icons={playerIcons}
    />
  );
}

export default VideoPlayer;

This configuration creates a complete icon set using Lucide's components. Each icon is sized consistently at 26 pixels, ensuring uniform appearance across all controls. Lucide React automatically handles accessibility attributes and proper SVG rendering.

Why Lucide Works Well: The library provides consistent stroke widths and visual weight across all icons, creating a cohesive look. Its small bundle size and tree-shaking support means you only include the icons you actually use, keeping your application lean.

React Icons

React Icons aggregates multiple popular icon libraries into a single package, giving you access to thousands of icons from Font Awesome, Material Design, Heroicons, and more.

Install React Icons:

npm install react-icons

Configure your player using icons from different collections within React Icons:

src/components/VideoPlayer.jsx
import { CustomVideoPlayer } from "@ntxmjs/react-custom-video-player";
import {
  IoPlay,
  IoPause,
  IoVolumeHigh,
  IoVolumeMute,
  IoExpand,
  IoContract,
  IoTvOutline,
  IoSettings,
  IoSpeedometer,
  IoText,
  IoArrowBack,
  IoCheckmark,
} from "react-icons/io5";
import { MdHd, MdTimer } from "react-icons/md";

function VideoPlayer() {
  const playerIcons = {
    play: <IoPlay size={26} />,
    pause: <IoPause size={26} />,
    volume: <IoVolumeHigh size={26} />,
    volumeMute: <IoVolumeMute size={26} />,
    fullscreen: <IoExpand size={26} />,
    exitFullscreen: <IoContract size={26} />,
    pip: <IoTvOutline size={26} />,
    settings: <IoSettings size={26} />,
    speed: <IoSpeedometer size={26} />,
    cc: <IoText size={26} />,
    back: <IoArrowBack size={26} />,
    check: <IoCheckmark size={26} />,
    hdChip: <MdHd size={26} />,
    sleepTimer: <MdTimer size={26} />,
  };

  return (
    <CustomVideoPlayer
      src="https://example.com/video.m3u8"
      poster="https://example.com/poster.jpg"
      icons={playerIcons}
    />
  );
}

This example combines Ionicons 5 icons with Material Design icons, demonstrating React Icons' flexibility. You can mix and match icons from different libraries while maintaining consistent sizing.

Choosing Icons from React Icons: The library's variety can be overwhelming. Start by exploring a single icon family that matches your design aesthetic. Ionicons 5 offers modern, rounded icons, while Material Design provides sharp, recognizable symbols. Consistency matters more than variety—stick with one or two icon families throughout your interface.

Heroicons

Heroicons, designed by the creators of Tailwind CSS, offers beautifully crafted icons in both outline and solid styles, making it perfect for applications using Tailwind.

Install Heroicons:

npm install @heroicons/react

Configure using Heroicons' outline style:

src/components/VideoPlayer.jsx
import { CustomVideoPlayer } from "@ntxmjs/react-custom-video-player";
import {
  PlayIcon,
  PauseIcon,
  SpeakerWaveIcon,
  SpeakerXMarkIcon,
  ArrowsPointingOutIcon,
  ArrowsPointingInIcon,
  TvIcon,
  Cog6ToothIcon,
  BoltIcon,
  LanguageIcon,
  ArrowLeftIcon,
  CheckIcon,
  ClockIcon,
} from "@heroicons/react/24/outline";
import { Square3Stack3DIcon } from "@heroicons/react/24/solid";

function VideoPlayer() {
  const playerIcons = {
    play: <PlayIcon className="w-6 h-6" />,
    pause: <PauseIcon className="w-6 h-6" />,
    volume: <SpeakerWaveIcon className="w-6 h-6" />,
    volumeMute: <SpeakerXMarkIcon className="w-6 h-6" />,
    fullscreen: <ArrowsPointingOutIcon className="w-6 h-6" />,
    exitFullscreen: <ArrowsPointingInIcon className="w-6 h-6" />,
    pip: <TvIcon className="w-6 h-6" />,
    settings: <Cog6ToothIcon className="w-6 h-6" />,
    speed: <BoltIcon className="w-6 h-6" />,
    cc: <LanguageIcon className="w-6 h-6" />,
    back: <ArrowLeftIcon className="w-6 h-6" />,
    check: <CheckIcon className="w-6 h-6" />,
    hdChip: <Square3Stack3DIcon className="w-6 h-6" />,
    sleepTimer: <ClockIcon className="w-6 h-6" />,
  };

  return (
    <CustomVideoPlayer
      src="https://example.com/video.m3u8"
      poster="https://example.com/poster.jpg"
      icons={playerIcons}
    />
  );
}

Heroicons uses Tailwind's sizing utilities instead of a size prop. The w-6 h-6 classes create 24-pixel icons, which you can adjust to w-7 h-7 for closer to 26 pixels if desired.

Icon Sizing with Heroicons:

Heroicons doesn't use a size prop like other libraries. Instead, control icon dimensions through Tailwind CSS classes. The w-6 h-6 classes create 24Ă—24 pixel icons, while w-7 h-7 produces 28Ă—28 pixels. Choose the size that best fits your player's design.

Creating Custom SVG Icons

For complete control over your icon design, create custom SVG components that perfectly match your brand identity. This approach requires more initial work but offers unlimited customization.

Basic Custom SVG Icons

Create a dedicated icons file to organize your custom components:

src/components/icons/PlayerIcons.jsx
export const CustomPlayIcon = ({ size = 26, color = "currentColor" }) => (
  <svg
    width={size}
    height={size}
    viewBox="0 0 24 24"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
  >
    <path
      d="M8 5v14l11-7L8 5z"
      fill={color}
    />
  </svg>
);

export const CustomPauseIcon = ({ size = 26, color = "currentColor" }) => (
  <svg
    width={size}
    height={size}
    viewBox="0 0 24 24"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
  >
    <path
      d="M6 4h4v16H6V4zm8 0h4v16h-4V4z"
      fill={color}
    />
  </svg>
);

export const CustomVolumeIcon = ({ size = 26, color = "currentColor" }) => (
  <svg
    width={size}
    height={size}
    viewBox="0 0 24 24"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
  >
    <path
      d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"
      fill={color}
    />
  </svg>
);

// Create similar exports for all other required icons...

Then use your custom icons in the player:

src/components/VideoPlayer.jsx
import { CustomVideoPlayer } from "@ntxmjs/react-custom-video-player";
import {
  CustomPlayIcon,
  CustomPauseIcon,
  CustomVolumeIcon,
  // ... import all custom icons
} from "./icons/PlayerIcons";

function VideoPlayer() {
  const playerIcons = {
    play: <CustomPlayIcon size={26} />,
    pause: <CustomPauseIcon size={26} />,
    volume: <CustomVolumeIcon size={26} />,
    // ... configure remaining icons
  };

  return (
    <CustomVideoPlayer
      src="https://example.com/video.m3u8"
      poster="https://example.com/poster.jpg"
      icons={playerIcons}
    />
  );
}

Custom SVG icons give you complete control over every path, color, and animation. You can create icons that perfectly align with your brand guidelines, including custom colors, stroke widths, and visual styles that differentiate your player from others.

Best Practices for Custom SVGs: Always use the viewBox attribute to ensure proper scaling. Set dimensions based on props rather than hardcoding them. Use currentColor for the fill or stroke to allow CSS color inheritance. Keep the SVG markup clean and optimized—remove unnecessary attributes and comments from design tools.

Animated Icons with Framer Motion

Framer Motion brings your player to life with smooth, professional animations on icon transitions. This creates a premium feel and provides visual feedback that enhances user experience.

Install Framer Motion:

npm install framer-motion

Create animated icon components:

src/components/icons/AnimatedIcons.jsx
import { motion } from "framer-motion";

export const AnimatedPlayIcon = ({ size = 26 }) => (
  <motion.svg
    width={size}
    height={size}
    viewBox="0 0 24 24"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
    whileHover={{ scale: 1.1 }}
    whileTap={{ scale: 0.95 }}
    transition={{ type: "spring", stiffness: 400, damping: 17 }}
  >
    <motion.path
      d="M8 5v14l11-7L8 5z"
      fill="currentColor"
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      transition={{ duration: 0.3 }}
    />
  </motion.svg>
);

export const AnimatedPauseIcon = ({ size = 26 }) => (
  <motion.svg
    width={size}
    height={size}
    viewBox="0 0 24 24"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
    whileHover={{ scale: 1.1 }}
    whileTap={{ scale: 0.95 }}
    transition={{ type: "spring", stiffness: 400, damping: 17 }}
  >
    <motion.path
      d="M6 4h4v16H6V4zm8 0h4v16h-4V4z"
      fill="currentColor"
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      transition={{ duration: 0.3 }}
    />
  </motion.svg>
);

export const AnimatedVolumeIcon = ({ size = 26 }) => (
  <motion.svg
    width={size}
    height={size}
    viewBox="0 0 24 24"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
    whileHover={{ rotate: 12 }}
    whileTap={{ scale: 0.9 }}
    transition={{ type: "spring", stiffness: 300 }}
  >
    <path
      d="M3 9v6h4l5 5V4L7 9H3z"
      fill="currentColor"
    />
    <motion.path
      d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"
      fill="currentColor"
      animate={{ scale: [1, 1.2, 1] }}
      transition={{ duration: 1.5, repeat: Infinity, ease: "easeInOut" }}
    />
  </motion.svg>
);

export const AnimatedSettingsIcon = ({ size = 26 }) => (
  <motion.svg
    width={size}
    height={size}
    viewBox="0 0 24 24"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
    whileHover={{ rotate: 180 }}
    transition={{ duration: 0.6, ease: "easeInOut" }}
  >
    <path
      d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"
      fill="currentColor"
    />
  </motion.svg>
);

Use animated icons in your player:

src/components/VideoPlayer.jsx
import { CustomVideoPlayer } from "@ntxmjs/react-custom-video-player";
import {
  AnimatedPlayIcon,
  AnimatedPauseIcon,
  AnimatedVolumeIcon,
  AnimatedSettingsIcon,
  // ... other animated icons
} from "./icons/AnimatedIcons";

function VideoPlayer() {
  const playerIcons = {
    play: <AnimatedPlayIcon size={26} />,
    pause: <AnimatedPauseIcon size={26} />,
    volume: <AnimatedVolumeIcon size={26} />,
    settings: <AnimatedSettingsIcon size={26} />,
    // ... configure remaining icons
  };

  return (
    <CustomVideoPlayer
      src="https://example.com/video.m3u8"
      poster="https://example.com/poster.jpg"
      icons={playerIcons}
    />
  );
}

The animations add subtle but noticeable polish. The play icon scales up on hover and down on click, providing tactile feedback. The volume icon includes a pulsing animation on the sound waves, suggesting audio output. The settings icon rotates when hovered, clearly indicating it's interactive.

Animation Guidelines: Keep animations subtle and purposeful. Overly dramatic effects distract from the content. Use spring-based animations for natural, physics-based motion. Ensure animations complete quickly—users shouldn't wait for icons to finish animating before the action executes. Test animations on lower-powered devices to ensure smooth performance.

Performance Considerations:

Animated icons add visual polish but increase bundle size and can impact performance on lower-end devices. Consider using animated icons selectively for key interactions rather than every icon in the player. Profile your application's performance to ensure animations don't cause frame rate drops during video playback.

Mixing Icon Sources

You don't need to commit to a single approach. Combine different icon sources based on your needs, using library icons for standard elements and custom icons for unique branding opportunities.

src/components/VideoPlayer.jsx
import { CustomVideoPlayer } from "@ntxmjs/react-custom-video-player";
import { Play, Pause, Volume2, VolumeX } from "lucide-react";
import { CustomBrandedSettings } from "./icons/BrandedIcons";
import { AnimatedCheckIcon } from "./icons/AnimatedIcons";
import { MdHd } from "react-icons/md";

function VideoPlayer() {
  const playerIcons = {
    // Standard controls from Lucide
    play: <Play size={26} />,
    pause: <Pause size={26} />,
    volume: <Volume2 size={26} />,
    volumeMute: <VolumeX size={26} />,

    // Custom branded icons
    settings: <CustomBrandedSettings size={26} />,

    // Animated feedback icon
    check: <AnimatedCheckIcon size={26} />,

    // Material Design HD badge
    hdChip: <MdHd size={26} />,

    // ... other icons
  };

  return (
    <CustomVideoPlayer
      src="https://example.com/video.m3u8"
      poster="https://example.com/poster.jpg"
      icons={playerIcons}
    />
  );
}

This hybrid approach leverages the strengths of each source. Standard controls use reliable library icons that users recognize immediately. Brand-specific features use custom icons that reinforce your identity. Interactive feedback elements use animations for enhanced user experience.

Icon Color and Styling

The player automatically applies appropriate colors to icons based on the active theme, but you can override this behavior when needed.

src/components/VideoPlayer.jsx
import { CustomVideoPlayer } from "@ntxmjs/react-custom-video-player";
import { Play, Pause } from "lucide-react";

function VideoPlayer() {
  const playerIcons = {
    play: <Play size={26} color="#ffffff" />,
    pause: <Pause size={26} color="#ffffff" />,
    // ... other icons
  };

  return (
    <CustomVideoPlayer
      src="https://example.com/video.m3u8"
      poster="https://example.com/poster.jpg"
      icons={playerIcons}
      theme="dark"
    />
  );
}

Explicitly setting colors overrides the theme's default icon colors. Use this sparingly—the theme system is designed to ensure proper contrast and visibility. Only override colors when you have specific branding requirements that the theme system doesn't accommodate.

Accessibility Reminder:

When customizing icon colors, always ensure sufficient contrast between icons and their background. The WCAG recommends a contrast ratio of at least 3:1 for large graphical objects like icons. Test your color choices with accessibility tools to ensure all users can clearly see and interact with player controls.

Troubleshooting Icon Issues

If icons don't appear or look incorrect, check these common issues:

Missing Icons: Verify all fifteen required icons are present in your configuration. Missing even one icon will cause runtime errors. Use TypeScript or add validation to catch missing icons during development.

Incorrect Sizing: Ensure all icons use consistent sizing. Mismatched sizes create a unprofessional appearance. If using library icons with different sizing mechanisms, normalize them with wrapper components.

Import Errors: Double-check import paths and icon names. Typos in icon names are a common source of errors that may not be immediately obvious.

Color Issues: If icons appear invisible or hard to see, they may not be inheriting colors correctly. Ensure your SVG icons use currentColor for fills or strokes, allowing the theme system to control their appearance.

Animation Performance: If animated icons cause stuttering or performance issues, reduce animation complexity or disable animations on lower-powered devices. Use Framer Motion's reducedMotion feature to respect user preferences.

Next Steps

With your icons configured, explore these related topics:

Captions Configuration: Learn how to add multi-language subtitles to enhance accessibility and reach international audiences.

Theming: Customize the player's visual appearance, including the colors and styles that affect how your icons are displayed.

Props: Discover all available configuration options to fine-tune player behavior and appearance.

Icon configuration establishes the visual foundation of your player. Whether you choose library icons for speed, custom icons for branding, or animated icons for polish, the player adapts to your choices while maintaining a consistent, professional user experience.