# Browser Window

A compact browser chrome frame for screenshots and previews.

## Installation

```bash
npx shadcn@latest add https://ui.jarv.is/r/browser-window.json
```

[Registry JSON](https://ui.jarv.is/r/browser-window.json)

## Preview

```tsx
import { BrowserWindow, BrowserWindowContent } from "@/components/ui/browser-window";

export function Preview() {
  return (
    <BrowserWindow
      address="ui.shadcn.com"
      addressHref="https://ui.shadcn.com"
      className="w-full max-w-2xl"
    >
      <BrowserWindowContent className="aspect-video bg-muted p-6">
        <div className="grid size-full place-items-center rounded-md border border-dashed bg-background">
          <div className="flex flex-col items-center gap-2 text-center">
            <div className="h-2 w-28 rounded-full bg-primary/70" />
            <div className="h-2 w-44 rounded-full bg-muted-foreground/30" />
            <div className="h-2 w-36 rounded-full bg-muted-foreground/20" />
          </div>
        </div>
      </BrowserWindowContent>
    </BrowserWindow>
  );
}
```


## Source

### ui/browser-window.tsx

```tsx
import type * as React from "react";

import { cn } from "@/lib/utils";

type BrowserWindowProps = React.ComponentProps<"div"> & {
  address?: React.ReactNode;
  addressHref?: string;
};

function BrowserWindow({
  address = "about:blank",
  addressHref,
  className,
  children,
  ...props
}: BrowserWindowProps) {
  return (
    <div
      data-slot="browser-window"
      className={cn(
        "overflow-hidden rounded-lg border bg-card text-card-foreground shadow-sm",
        className,
      )}
      {...props}
    >
      <div
        data-slot="browser-window-toolbar"
        className="flex h-9 items-center gap-2 border-b border-zinc-200 bg-zinc-100 px-2 dark:border-zinc-800 dark:bg-zinc-900"
      >
        <div
          aria-hidden="true"
          data-slot="browser-window-controls"
          className="flex shrink-0 items-center gap-1.5"
        >
          <div className="size-2 rounded-full bg-[#FF5F57]" />
          <div className="size-2 rounded-full bg-[#FEBC2E]" />
          <div className="size-2 rounded-full bg-[#28C840]" />
        </div>
        <div
          aria-label="Address"
          data-slot="browser-window-address"
          className="flex min-w-0 flex-1 items-center rounded-sm bg-zinc-200 px-2 py-[3px] dark:bg-zinc-800"
        >
          {addressHref ? (
            <a
              href={addressHref}
              target="_blank"
              rel="noreferrer"
              className="block w-full truncate text-center text-[10px] font-medium text-zinc-500 dark:text-zinc-400"
            >
              {address}
            </a>
          ) : (
            <span className="block truncate">{address}</span>
          )}
        </div>
      </div>
      {children}
    </div>
  );
}

function BrowserWindowContent({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="browser-window-content"
      className={cn("overflow-hidden bg-background", className)}
      {...props}
    />
  );
}

function BrowserWindowImage({ className, alt, ...props }: React.ComponentProps<"img">) {
  return (
    <img
      data-slot="browser-window-image"
      alt={alt}
      className={cn("block size-full object-cover", className)}
      {...props}
    />
  );
}

export { BrowserWindow, BrowserWindowContent, BrowserWindowImage };
```



## Usage

### Basic frame

Use the browser window to frame product screenshots, app previews, or embedded content with a
lightweight browser chrome.

```tsx
import { BrowserWindow, BrowserWindowContent } from "@/components/ui/browser-window";

export function Example() {
  return (
    <BrowserWindow address="example.com">
      <BrowserWindowContent className="aspect-video" />
    </BrowserWindow>
  );
}
```

### Linked address

Pass `addressHref` when the address should open the live page in a new tab.

```tsx
import { BrowserWindow, BrowserWindowContent } from "@/components/ui/browser-window";

export function DocsPreview() {
  return (
    <BrowserWindow address="ui.jarv.is/components" addressHref="https://ui.jarv.is/components">
      <BrowserWindowContent className="aspect-video bg-muted p-6">
        <div className="grid size-full place-items-center rounded-md bg-background">
          Components
        </div>
      </BrowserWindowContent>
    </BrowserWindow>
  );
}
```

### Screenshots

Use `BrowserWindowImage` when the framed content is a static screenshot.

```tsx
import {
  BrowserWindow,
  BrowserWindowContent,
  BrowserWindowImage,
} from "@/components/ui/browser-window";

export function ScreenshotFrame() {
  return (
    <BrowserWindow address="app.example.com/dashboard">
      <BrowserWindowContent className="aspect-video">
        <BrowserWindowImage src="/dashboard.png" alt="Dashboard overview" />
      </BrowserWindowContent>
    </BrowserWindow>
  );
}
```

### Embedded content

The content area is just a styled container, so you can render live UI inside it.

```tsx
import { BrowserWindow, BrowserWindowContent } from "@/components/ui/browser-window";

export function EmptyStatePreview() {
  return (
    <BrowserWindow address="localhost:3000">
      <BrowserWindowContent className="p-8">
        <div className="rounded-lg border border-dashed p-8 text-center">
          No environments yet.
        </div>
      </BrowserWindowContent>
    </BrowserWindow>
  );
}
```

