← Back to Resources

BrowserFrame Component

A React component that renders a stylized browser window frame

A reusable React component that displays a browser chrome UI with customizable content. Supports both image and video content with smooth transitions.

ReactUI ComponentsBrowser FrameTailwind CSS
January 2026Components

Overview

BrowserFrame is a React component that renders a stylized browser window frame with customizable content. It displays a browser chrome UI (traffic lights, URL bar, action buttons) with an image or video content area. Perfect for showcasing web applications, demos, or screenshots in a polished browser context.

Features

  • Browser chrome UI with macOS-style traffic light buttons
  • Address bar with lock icon and URL display
  • Action buttons (share, add, copy)
  • Supports both image and video content
  • Automatic image-to-video transition when video loads
  • Smooth opacity transitions for content switching
  • Responsive design with Tailwind CSS
  • Fully customizable via props

Installation

The component requires react-icons for the browser chrome icons. Install it with:

npm install react-icons

Usage

Import the component:

import { BrowserFrame } from "./components/ui/Frames";

Basic Example with Image

<BrowserFrame 
  imageSrc="/screenshot.png" 
  imageAlt="Website screenshot"
  url="example.com"
/>
example.com
Example browser frame

Example with Video

When a video source is provided, the component will automatically transition from the image to the video once it's loaded:

<BrowserFrame 
  imageSrc="/placeholder.png"
  videoSrc="/demo.mp4"
  url="app.example.com"
  className="my-custom-class"
/>

Props

The component accepts the following props:

  • imageSrc (string, optional): Image source URL. Defaults to "/web-placeholder.png". Used as fallback when video is provided.
  • imageAlt (string, optional): Alt text for the image. Defaults to "Browser Placeholder".
  • url (string, optional): URL displayed in the browser address bar. Defaults to "www.example.com".
  • className (string, optional): Additional CSS classes to apply to the root element. Defaults to empty string.
  • videoSrc (string, optional): Video source URL. When provided, video will auto-play, loop, and be muted. The component will smoothly transition from image to video once loaded.

Component Code

Here's the complete component implementation:

import { useState, useRef, useEffect } from "react";
import {
  IoAddOutline,
  IoCopyOutline,
  IoLockClosed,
  IoRefreshOutline,
  IoShareOutline,
} from "react-icons/io5";

export function BrowserFrame({
  imageSrc = "/web-placeholder.png",
  imageAlt = "Browser Placeholder",
  url = "www.example.com",
  className = "",
  videoSrc,
}) {
  const [isVideoLoaded, setIsVideoLoaded] = useState(false);
  const videoRef = useRef(null);

  useEffect(() => {
    if (videoSrc && videoRef.current) {
      const video = videoRef.current;
      const handleCanPlay = () => {
        setIsVideoLoaded(true);
      };

      video.addEventListener("canplay", handleCanPlay);
      video.load();

      return () => {
        video.removeEventListener("canplay", handleCanPlay);
      };
    }
  }, [videoSrc]);

  return (
    <figure
      className={`relative z-1 max-w-full w-3xl h-auto rounded-b-lg ${className}`}
    >
      <div className="relative flex items-center bg-gray-800 rounded-t-lg py-2 px-4 justify-between">
        <div className="flex gap-x-1.5">
          <span className="size-2 bg-red-600 rounded-full"></span>
          <span className="size-2 bg-yellow-500 rounded-full"></span>
          <span className="size-2 bg-green-600 rounded-full"></span>
        </div>
        <div className="flex justify-center items-center size-full max-w-48 md:max-w-sm bg-gray-700 text-[.5rem] text-gray-400 rounded-sm py-[2px] px-1">
          <span className="flex items-center gap-x-1 flex-1 justify-center">
            <IoLockClosed className="size-2.5" />
            {url}
          </span>
          <IoRefreshOutline className="size-3 text-gray-400" />
        </div>
        <div className="flex items-center gap-x-2">
          <IoShareOutline className="size-3 text-gray-400" />
          <IoAddOutline className="size-4 text-gray-400" />
          <IoCopyOutline className="size-3 text-gray-400" />
        </div>
      </div>

      <div className="bg-gray-800 rounded-b-lg relative">
        <img
          className={`max-w-full h-auto rounded-b-lg object-cover transition-opacity duration-300 ${
            videoSrc && isVideoLoaded ? "opacity-0" : "opacity-100"
          }`}
          src={imageSrc}
          alt={imageAlt}
        />
        {videoSrc && (
          <video
            ref={videoRef}
            className={`absolute inset-0 w-full h-full rounded-b-lg object-cover transition-opacity duration-300 ${
              isVideoLoaded ? "opacity-100" : "opacity-0"
            }`}
            src={videoSrc}
            autoPlay
            loop
            muted
            playsInline
          />
        )}
      </div>
    </figure>
  );
}

Styling

The component uses Tailwind CSS for styling. The browser chrome uses a dark gray theme (bg-gray-800, bg-gray-700) with subtle text colors. The traffic lights are styled with red, yellow, and green colors. All styling can be customized via the className prop or by modifying the component's Tailwind classes.

Browser Support

The component works in all modern browsers that support React and CSS transitions. Video support depends on browser video codec support.

License

This component is provided as-is for use in your projects. Feel free to modify and adapt it to your needs.