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.
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-iconsUsage
Import the component:
import { BrowserFrame } from "./components/ui/Frames";Basic Example with Image
<BrowserFrame
imageSrc="/screenshot.png"
imageAlt="Website screenshot"
url="example.com"
/>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.