> ## Documentation Index
> Fetch the complete documentation index at: https://docs.brandfetch.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Use Brandfetch with shadcn/ui

> Add brand logos, company search, logo walls and brand cards to a shadcn/ui project with one CLI command.

Brandfetch publishes a [shadcn/ui](https://ui.shadcn.com) registry with six React components for logos, company search, logo walls and brand cards. The shadcn CLI copies the source into your project, so you own the code and can restyle it like the rest of your UI.

## Prerequisites

* A shadcn/ui project with Tailwind CSS v4
* A [Brandfetch account](https://developers.brandfetch.com/) with an active client ID

## Quickstart

**1. Install the components**

Install everything, or only the component you need:

```bash All components theme={null}
npx shadcn@latest add https://brandfetch.com/r/all.json
```

```bash One component theme={null}
npx shadcn@latest add https://brandfetch.com/r/logo.json
```

Each component also installs a shared helper, `lib/brandfetch.ts`.

**2. Add your credentials**

The CLI adds the variables to `.env.local`. Fill them in:

```bash .env.local theme={null}
NEXT_PUBLIC_BRANDFETCH_CLIENT_ID=your-client-id
BRANDFETCH_API_KEY=your-api-key # optional, Brand Card only
```

| Credential | Used by | Get it |
| - | - | - |
| Client ID | Every component except Brand Card. Safe to expose in the browser. | [Developer Portal](https://developers.brandfetch.com/register) |
| API key | Brand Card only. Secret, server only. | [API keys page](https://developers.brandfetch.com/dashboard/keys) |

**3. Render a logo**

```tsx theme={null}
import { Logo } from "@/components/ui/logo"

export function Customer() {
  return <Logo domain="nike.com" />
}
```

## Components

To install one component, put its name in the URL: `https://brandfetch.com/r/<name>.json`.

| Component | Name | What it does |
| - | - | - |
| [Logo](#logo) | `logo` | One brand icon, symbol or wordmark |
| [Logo Avatar](#logo-avatar) | `logo-avatar` | Brand icons in a shadcn Avatar, alone or stacked |
| [Brand Search](#brand-search) | `brand-search` | Company autocomplete |
| [Logo Wall](#logo-wall) | `logo-wall` | A "Trusted by" grid |
| [Logo Marquee](#logo-marquee) | `logo-marquee` | The same logos in a scrolling strip |
| [Brand Card](#brand-card) | `brand-card` | Banner, logo, description, colors and fonts |

### Logo

Shows one asset from the [Logo API](https://docs.brandfetch.com/logo-api/overview.md). Look a brand up by domain, ticker, ISIN or crypto symbol:

```tsx theme={null}
<Logo domain="nike.com" />
<Logo ticker="AAPL" type="logo" size={32} />
<Logo crypto="BTC" />
```

Not every brand has every asset. Pass a list to `type` and the component tries each one in order:

```tsx theme={null}
<Logo domain="acme.dev" type={["logo", "symbol", "icon"]} fallback="initials" />
```

> [accordion] Logo props
>
> **domain | ticker | isin | crypto** `string` *required*
>
> The brand. Use `identifier` if you don't know the type.
>
> **type** `"icon" | "symbol" | "logo" | array` (default: icon)
>
> `icon` is the square app icon, `symbol` the bare mark, `logo` the wordmark. Pass a list to try in order.
>
> **size** `number` (default: 40)
>
> Height in pixels. Wordmarks keep their width.
>
> **theme** `"light" | "dark" | "auto"`
>
> `auto` follows your app's dark mode. Defaults to `auto` for symbols and wordmarks.
>
> **fallback** `string | ReactNode`
>
> Shown when the brand has no asset: `lettermark`, `brandfetch`, `transparent`, `initials`, `none`, or your own element.
>
> **balance** `boolean` (default: false)
>
> Sizes wordmarks by area, so wide and compact logos look the same weight.
>
> **label** `string`
>
> Brand name for the `alt` text and initials.

### Logo Avatar

Shows a brand icon in a shadcn Avatar, with the brand's initials while it loads. `LogoAvatarGroup` shows the first `max` icons and a `+N` count for the rest.

```tsx theme={null}
import { LogoAvatar, LogoAvatarGroup } from "@/components/ui/logo-avatar"

<LogoAvatar domain="stripe.com" size={40} radius="md" />

<LogoAvatarGroup
  brands={["vercel.com", "linear.app", "notion.so", "figma.com"]}
  max={3}
/>
```

> [accordion] Logo Avatar props
>
> **size** `number` (default: 32)
>
> Width and height in pixels.
>
> **radius** `"full" | "lg" | "md" | "sm" | "none" | number` (default: full)
>
> Named sizes scale with the avatar. A number is pixels.
>
> **max** `number`
>
> `LogoAvatarGroup` only. Icons to show before the `+N` count.

### Brand Search

A company autocomplete built on the shadcn Combobox and the [Brand Search API](https://docs.brandfetch.com/brand-search-api/overview.md). It runs in the browser with your client ID, so you don't need an API route.

```tsx theme={null}
import { BrandSearch } from "@/components/brand-search"

<BrandSearch
  onValueChange={(brand) => {
    if (brand) setCompany(brand.domain)
  }}
/>
```

> [accordion] Brand Search props
>
> **onValueChange** `(brand: BrandSearchResult | null) =\> void`
>
> Called with the picked brand (`name`, `domain`, `icon`, `brandId`), or `null` when cleared.
>
> **value** `BrandSearchResult | null`
>
> The selected brand, for a controlled input.
>
> **maxResults** `number` (default: 8)
>
> Maximum suggestions.
>
> **debounce** `number` (default: 250)
>
> Milliseconds to wait after typing stops.
>
> **placeholder** `string` (default: Search companies…)
>
> Input placeholder.

Save the domain the user picks, not the search result. See [usage rules](#usage-rules).

### Logo Wall

A grid of customer or partner logos, balanced by area. A brand with no wordmark falls back to its symbol, then its icon.

```tsx theme={null}
import { LogoWall } from "@/components/logo-wall"

<LogoWall
  brands={["stripe.com", "vercel.com", "linear.app", "notion.so"]}
  columns={4}
/>
```

> [accordion] Logo Wall props
>
> **brands** `(string | \{ domain, label?, href? \})[]` *required*
>
> Domains, or an object to label or link a tile.
>
> **type** `"logo" | "symbol" | "icon"` (default: logo)
>
> Wordmarks, bare marks or app icons.
>
> **columns** `2 | 3 | 4 | 5 | 6` (default: 4)
>
> Columns on medium screens and up. Mobile shows two.
>
> **grayscale** `boolean` (default: true)
>
> Grayscale until hovered.
>
> **bordered** `boolean` (default: true)
>
> Borders between cells.

### Logo Marquee

The same logos in a looping strip. It pauses on hover and stays still when reduced motion is on.

```tsx theme={null}
import { LogoMarquee } from "@/components/logo-marquee"

<LogoMarquee brands={["stripe.com", "vercel.com", "linear.app"]} duration={30} />
```

> [accordion] Logo Marquee props
>
> **brands** `string[]` *required*
>
> Domains to show.
>
> **type** `"logo" | "symbol" | "icon"` (default: logo)
>
> Wordmarks, bare marks or app icons.
>
> **duration** `number` (default: 40)
>
> Seconds per loop.
>
> **direction** `"left" | "right"` (default: left)
>
> Scroll direction.
>
> **pauseOnHover** `boolean` (default: true)
>
> Stops while the pointer is over the strip.

### Brand Card

A company's banner, icon, name and description, with optional colors, fonts and links. The data comes from the [Brand API](https://docs.brandfetch.com/brand-api/overview.md), which needs your secret API key, so fetch it on the server with `getBrand()`:

```tsx theme={null}
import { BrandCard } from "@/components/brand-card"
import { getBrand } from "@/lib/brandfetch"

export default async function Page() {
  const brand = await getBrand("stripe.com")
  return <BrandCard brand={brand} show={["colors", "fonts"]} />
}
```

Use `BrandCardSkeleton` as the Suspense fallback.

> [accordion] Brand Card props
>
> **brand** `Brand` *required*
>
> The response from `getBrand()`.
>
> **show** `("colors" | "fonts" | "links")[]` (default: \[])
>
> Extra sections below the description.
>
> **href** `string`
>
> Turns the card into a link.

> [!TIP]
>
> Each `getBrand()` call is one Brand API request and counts toward your plan's quota.

## Helpers

`lib/brandfetch.ts` also works on its own:

| Function | Runs in | What it does |
| - | - | - |
| `logoUrl(options)` | Anywhere | Builds a Logo API URL. |
| `searchBrands(query)` | Browser | Calls the Brand Search API with your client ID. |
| `getBrand(identifier)` | Server only | Calls the Brand API with your API key. |

## Usage rules

The components follow these rules. Keep them if you edit the code:

* Load logos from `cdn.brandfetch.io` in an `<img>` tag. Don't download, proxy or re-host them. See [hotlinking](https://docs.brandfetch.com/logo-api/overview.md).
* Use Brand Search results for autocomplete only. Don't store them.
* Keep `BRANDFETCH_API_KEY` on the server. Never import `getBrand()` into client code.

## FAQ

> [accordion] Do I need Next.js?
>
> No. Outside Next.js, the `NEXT_PUBLIC_` variable isn't read automatically, so pass your client ID with the `clientId` prop.

> [accordion] How do I update the components?
>
> Run the same `add` command again. The CLI asks before it overwrites existing files.

> [accordion] Do I need to show attribution?
>
> No. The Logo API and Brand Search API are free and don't require attribution.

> [accordion] Why do I see the Brandfetch placeholder instead of a logo?
>
> The brand has no asset of the type you asked for. Pass a list to `type`, or set `fallback` to `initials`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.