> ## 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.

# Profiles & directory

> Put verified logos and brand data on every company record, in account lists, CRM contacts, job listings, and logo walls

export const DynamicFaviconDemo = () => {
  const brands = [{
    name: "Stripe",
    domain: "stripe.com"
  }, {
    name: "Dropbox",
    domain: "dropbox.com"
  }, {
    name: "Linear",
    domain: "linear.app"
  }, {
    name: "GitHub",
    domain: "github.com"
  }];
  const [active, setActive] = useState(brands[0]);
  return <div className="w-full max-w-[420px]">
      <div className="flex gap-2 mb-3 flex-wrap">
        {brands.map(b => <button key={b.domain} onClick={() => setActive(b)} className={`px-3 py-1 rounded-full text-[13px] font-medium border transition-colors ${active.domain === b.domain ? "bg-[#0084FF] border-[#0084FF] text-white" : "border-[#63636333]"}`}>
            {b.name}
          </button>)}
      </div>
      <div className="rounded-t-xl border-t border-x border-[#63636333] bg-[#6363630d] pt-2 px-2 flex items-end">
        <div className="flex items-center gap-2 bg-[#ffffff] dark:bg-[#1c1d1f] rounded-t-lg px-3 py-2 border-t border-x border-[#63636326] max-w-[240px]">
          <img noZoom src={`https://cdn.brandfetch.io/domain/${active.domain}/w/32/h/32/fallback/lettermark?c=1bfwsmEH20zzEfSNTed`} alt={`${active.name} favicon`} className="w-4 h-4 rounded-sm shrink-0" />
          <span className="text-[13px] truncate text-[#111] dark:text-[#e5e5e5]">{active.name} — Dashboard</span>
          <span className="text-[#9ca3af] text-xs shrink-0">✕</span>
        </div>
      </div>
      <div className="border-x border-b border-[#63636333] rounded-b-xl bg-[#ffffff] dark:bg-[#1c1d1f] px-3 py-2.5 text-[13px] text-[#6b7280] flex items-center gap-2">
        <span>🔒</span>
        <span className="truncate">https://app.{active.domain}/dashboard</span>
      </div>
    </div>;
};

export const AnimatedMarqueeDemo = () => {
  const domains = ["shopify.com", "airbnb.com", "nike.com", "discord.com", "slack.com", "stripe.com", "dropbox.com", "reddit.com", "medium.com", "meta.com"];
  const track = [...domains, ...domains];
  return <div className="bf-marquee-fade w-full max-w-[520px] overflow-hidden">
      <style>{`
        .bf-marquee-fade { -webkit-mask-image: linear-gradient(to right, transparent, black 12%, black 88%, transparent); mask-image: linear-gradient(to right, transparent, black 12%, black 88%, transparent); }
        .bf-marquee-track { animation: bf-scroll 22s linear infinite; }
        .bf-marquee:hover .bf-marquee-track { animation-play-state: paused; }
        @keyframes bf-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
      `}</style>
      <div className="bf-marquee">
        <div className="bf-marquee-track flex items-center gap-6 w-max py-2">
          {track.map((domain, i) => <img noZoom key={i} src={`https://cdn.brandfetch.io/domain/${domain}/type/icon/w/80/h/80/fallback/lettermark?c=1bfwsmEH20zzEfSNTed`} alt={`${domain} logo`} className="h-10 w-10 rounded-xl shrink-0" />)}
        </div>
      </div>
    </div>;
};

export const AnimatedFlipWallDemo = () => {
  const pool = ["framer.com", "netflix.com", "airbnb.com", "uber.com", "lyft.com", "doordash.com", "tiktok.com", "snapchat.com", "producthunt.com", "reddit.com", "twitch.tv", "linkedin.com", "discord.com", "medium.com", "google.com", "microsoft.com", "apple.com", "amazon.com", "meta.com", "adobe.com", "salesforce.com", "nvidia.com", "samsung.com", "sony.com", "x.com", "slack.com", "vimeo.com", "dribbble.com", "stripe.com", "github.com", "gitlab.com", "dropbox.com", "zoom.us", "asana.com", "trello.com", "atlassian.com"];
  const src = d => `https://cdn.brandfetch.io/domain/${d}/type/icon/w/112/h/112/fallback/lettermark?c=1bfwsmEH20zzEfSNTed`;
  const tiles = Array.from({
    length: 18
  }, (_, i) => {
    const row = Math.floor(i / 6);
    const col = i % 6;
    return {
      a: pool[i],
      b: pool[i + 18],
      d: -((row + col) * 0.35),
      i
    };
  });
  return <div className="grid gap-6" style={{
    gridTemplateColumns: "repeat(6, 44px)"
  }}>
      <style>{`
        @keyframes bf-flip {
          0%, 42%  { transform: rotateY(0deg); }
          50%, 92% { transform: rotateY(180deg); }
          100%     { transform: rotateY(360deg); }
        }
      `}</style>
      {tiles.map(({a, b, d, i}) => <div key={i} style={{
    perspective: "700px"
  }} className="w-11 h-11">
          <div className="relative w-full h-full" style={{
    transformStyle: "preserve-3d",
    animationName: "bf-flip",
    animationDuration: "6s",
    animationTimingFunction: "ease-in-out",
    animationIterationCount: "infinite",
    animationDelay: `${d}s`
  }}>
            <img noZoom src={src(a)} alt={a} className="absolute inset-0 w-full h-full object-contain rounded-xl" style={{
    backfaceVisibility: "hidden",
    WebkitBackfaceVisibility: "hidden"
  }} />
            <img noZoom src={src(b)} alt={b} className="absolute inset-0 w-full h-full object-contain rounded-xl" style={{
    backfaceVisibility: "hidden",
    WebkitBackfaceVisibility: "hidden",
    transform: "rotateY(180deg)"
  }} />
          </div>
        </div>)}
    </div>;
};

export const AnimatedLogoSwapDemo = () => {
  const domains = ["airbnb.com", "slack.com", "discord.com", "linear.app", "stripe.com"];
  const src = d => `https://cdn.brandfetch.io/domain/${d}/type/icon/w/96/h/96/fallback/lettermark?c=1bfwsmEH20zzEfSNTed`;
  return <div className="flex items-center gap-3 text-lg font-medium">
      <style>{`
        @keyframes bf-logocycle {
          0%   { opacity: 1; transform: scale(1); }
          15%  { opacity: 1; transform: scale(1); }
          20%  { opacity: 0; transform: scale(0.9); }
          95%  { opacity: 0; transform: scale(0.9); }
          100% { opacity: 1; transform: scale(1); }
        }
      `}</style>
      <span>Trusted by</span>
      <span className="relative inline-block w-9 h-9 align-middle">
        {domains.map((d, i) => <img noZoom key={d} src={src(d)} alt={d} className="absolute inset-0 w-9 h-9 object-contain rounded-lg" style={{
    animationName: "bf-logocycle",
    animationDuration: "10s",
    animationTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
    animationIterationCount: "infinite",
    animationDelay: `${-(i * 2)}s`
  }} />)}
      </span>
      <span>and 20,000+ teams</span>
    </div>;
};

export const LogoCloudIconGridDemo = () => {
  const domains = ["medium.com", "airbnb.com", "meta.com", "slack.com", "netflix.com", "dropbox.com", "nike.com", "stripe.com", "linear.app", "discord.com", "github.com", "shopify.com", "gitlab.com", "twitch.tv", "zoom.us", "vercel.com", "reddit.com", "duolingo.com", "coinbase.com", "paypal.com", "uber.com", "adobe.com", "mailchimp.com", "asana.com"];
  return <div className="grid gap-4" style={{
    gridTemplateColumns: "repeat(6, 48px)"
  }}>
      {domains.map(domain => <img noZoom key={domain} src={`https://cdn.brandfetch.io/domain/${domain}/type/icon/w/112/h/112/fallback/lettermark?c=1bfwsmEH20zzEfSNTed`} alt={`${domain} icon`} className="w-12 h-12 rounded-xl" />)}
    </div>;
};

export const LogoCloudGridDemo = () => {
  const domains = ["airbnb.com", "github.com", "google.com", "intel.com", "okta.com", "canva.com", "attio.com", "linkedin.com"];
  return <div className="w-full grid grid-cols-2 sm:grid-cols-4 gap-x-2 gap-y-2">
      <style>{`
        .bf-logo-invert { filter: none; }
        .dark .bf-logo-invert { filter: brightness(0) invert(100%); }
      `}</style>
      {domains.map(domain => <div key={domain} className="flex items-center justify-center h-16 rounded-xl">
          <img src={`https://cdn.brandfetch.io/domain/${domain}/h/112/w/240/theme/dark/type/logo?c=1bfwsmEH20zzEfSNTed`} className="max-h-8 max-w-[60%] rounded-none w-auto object-contain block bf-logo-invert" alt={`${domain} logo`} noZoom={true} />
        </div>)}
    </div>;
};

export const BrandComparisonDemo = () => {
  const cols = [{
    name: "Stripe",
    domain: "stripe.com"
  }, {
    name: "Adyen",
    domain: "adyen.com"
  }, {
    name: "Square",
    domain: "squareup.com"
  }];
  const rows = [{
    label: "Founded",
    values: ["2010", "2006", "2009"]
  }, {
    label: "Pricing from",
    values: ["2.9% + 30¢", "Interchange++", "2.6% + 10¢"]
  }, {
    label: "Best for",
    values: ["Developers", "Enterprise", "In-person"]
  }];
  return <div className="w-full max-w-[460px] rounded-xl border border-[#63636333] bg-white dark:bg-[#1c1d1f] overflow-hidden">
      <div className="grid" style={{
    gridTemplateColumns: "1.2fr 1fr 1fr 1fr"
  }}>
        <div />
        {cols.map(c => <div key={c.domain} className="flex flex-col items-center gap-1.5 px-3 pt-4 pb-3">
            <img noZoom src={`https://cdn.brandfetch.io/domain/${c.domain}/type/icon/w/64/h/64/fallback/lettermark?c=1bfwsmEH20zzEfSNTed`} alt={`${c.name} logo`} className="w-8 h-8 rounded-lg" />
            <div className="text-[13px] font-semibold">{c.name}</div>
          </div>)}
        {rows.flatMap((r, ri) => [<div key={`${ri}-label`} className="flex items-center px-4 py-3 text-[13px] font-medium text-[#6b7280] border-t border-[#63636326]">
            {r.label}
          </div>, ...r.values.map((v, ci) => <div key={`${ri}-${ci}`} className="flex items-center justify-center px-3 py-3 text-[13px] text-center border-t border-[#63636326]">
              {v}
            </div>)])}
      </div>
    </div>;
};

export const JobCardGridDemo = () => {
  const jobs = [{
    domain: "dropbox.com",
    title: "Product Designer",
    company: "Dropbox · SF"
  }, {
    domain: "vercel.com",
    title: "DevRel Engineer",
    company: "Vercel · Remote"
  }, {
    domain: "shopify.com",
    title: "Growth Marketer",
    company: "Shopify · NYC"
  }, {
    domain: "stripe.com",
    title: "Backend Engineer",
    company: "Stripe · Remote"
  }, {
    domain: "linear.app",
    title: "Product Manager",
    company: "Linear · Remote"
  }, {
    domain: "airbnb.com",
    title: "Data Scientist",
    company: "Airbnb · Dublin"
  }];
  return <div className="w-full grid grid-cols-2 sm:grid-cols-3 gap-3.5">
      <style>{`
        .bf-job-card { transition: transform 150ms ease; }
        .bf-job-card:hover { transform: translateY(-4px); }
      `}</style>
      {jobs.map(job => <div key={job.title} className="bf-job-card p-4 rounded-xl border border-[#63636333] bg-white dark:bg-[#1c1d1f] cursor-pointer transition-shadow duration-150 hover:shadow-[0_12px_24px_#0000001f]">
          <img noZoom src={`https://cdn.brandfetch.io/domain/${job.domain}/w/72/h/72/fallback/lettermark?c=1bfwsmEH20zzEfSNTed`} alt={`${job.domain} logo`} className="w-9 h-9 rounded-lg" />
          <div className="mt-3 mb-0.5 text-sm font-semibold">{job.title}</div>
          <div className="text-xs text-[#6b7280]">{job.company}</div>
        </div>)}
    </div>;
};

export const JobListingRowDemo = () => {
  const jobs = [{
    domain: "stripe.com",
    title: "Senior Backend Engineer",
    company: "Stripe · Remote"
  }, {
    domain: "dropbox.com",
    title: "Product Designer",
    company: "Dropbox · San Francisco"
  }, {
    domain: "shopify.com",
    title: "Growth Marketer",
    company: "Shopify · New York"
  }, {
    domain: "linear.app",
    title: "Founding Engineer",
    company: "Linear · Remote"
  }];
  return <div className="w-full max-w-[380px] flex flex-col gap-1">
      {jobs.map(job => <div key={job.title} className="flex items-center gap-3 p-3 rounded-[10px] cursor-pointer transition-colors duration-150 hover:bg-[#6363631f]">
          <img noZoom src={`https://cdn.brandfetch.io/domain/${job.domain}/w/88/h/88/fallback/lettermark?c=1bfwsmEH20zzEfSNTed`} alt={`${job.domain} logo`} className="w-11 h-11 rounded-lg shrink-0" />
          <div>
            <div className="font-semibold text-[15px]">{job.title}</div>
            <div className="text-[#6b7280] text-[13px]">{job.company}</div>
          </div>
        </div>)}
    </div>;
};

export const PipelineRowsDemo = () => {
  const deals = [{
    domain: "stripe.com",
    company: "Stripe",
    amount: "$48,000",
    stage: "Negotiation",
    tone: "#16a34a"
  }, {
    domain: "dropbox.com",
    company: "Dropbox",
    amount: "$22,500",
    stage: "Proposal",
    tone: "#0084FF"
  }, {
    domain: "shopify.com",
    company: "Shopify",
    amount: "$12,000",
    stage: "Discovery",
    tone: "#9ca3af"
  }];
  return <div className="w-full max-w-[380px] flex flex-col gap-0.5">
      {deals.map(d => <div key={d.domain} className="flex items-center gap-3 py-2.5 px-3 rounded-[10px] hover:bg-[#6363631f] transition-colors duration-150">
          <img noZoom src={`https://cdn.brandfetch.io/domain/${d.domain}/w/72/h/72/fallback/lettermark?c=1bfwsmEH20zzEfSNTed`} alt={`${d.company} logo`} className="w-9 h-9 rounded-lg shrink-0" />
          <div className="flex-1 min-w-0">
            <div className="font-semibold text-sm">{d.company}</div>
            <div className="text-[12px]" style={{
    color: d.tone
  }}>{d.stage}</div>
          </div>
          <div className="font-semibold text-sm shrink-0">{d.amount}</div>
        </div>)}
    </div>;
};

export const EnrichedContactCardDemo = () => <div className="w-full max-w-[300px] rounded-xl border border-[#63636333] bg-white dark:bg-[#1c1d1f] p-5">
    <div className="flex items-center gap-3">
      <div className="w-11 h-11 rounded-full bg-[#635BFF] text-white flex items-center justify-center font-semibold shrink-0">
        SR
      </div>
      <div>
        <div className="font-semibold">Sarah Rivera</div>
        <div className="text-[13px] text-[#6b7280]">VP Engineering</div>
      </div>
    </div>
    <div className="mt-4 pt-4 border-t border-[#63636326] flex items-center gap-3">
      <img noZoom src="https://cdn.brandfetch.io/domain/stripe.com/w/72/h/72/fallback/lettermark?c=1bfwsmEH20zzEfSNTed" alt="Stripe logo" className="w-9 h-9 rounded-lg shrink-0" />
      <div>
        <div className="font-medium text-sm">Stripe</div>
        <div className="text-[12px] text-[#6b7280]">stripe.com</div>
      </div>
    </div>
    <div className="mt-3 flex flex-wrap gap-1.5">
      {["Fintech", "8,000 employees", "San Francisco"].map(t => <span key={t} className="text-[11px] rounded-full bg-[#6363631a] px-2 py-0.5 text-[#6b7280]">
          {t}
        </span>)}
    </div>
  </div>;

export const AccountDetailPanelDemo = () => <div className="w-full max-w-[300px] rounded-xl border border-[#63636333] bg-white dark:bg-[#1c1d1f] border-t-4 border-t-[#635BFF] p-6">
    <img noZoom src="https://cdn.brandfetch.io/domain/stripe.com/w/96/h/96/fallback/lettermark?c=1bfwsmEH20zzEfSNTed" alt="Stripe logo" className="w-12 h-12 rounded-lg" />
    <div className="mt-[14px] font-bold text-lg">Stripe</div>
    <div className="text-[13px] text-[#6b7280] mt-0.5">stripe.com · Fintech</div>
    <div className="flex gap-4 mt-[18px] pt-4 border-t border-[#63636326]">
      <div>
        <div className="text-[11px] text-[#6b7280] uppercase tracking-[0.04em]">Stage</div>
        <div className="text-sm font-semibold">Enterprise</div>
      </div>
      <div>
        <div className="text-[11px] text-[#6b7280] uppercase tracking-[0.04em]">Owner</div>
        <div className="text-sm font-semibold">A. Rivera</div>
      </div>
    </div>
  </div>;

export const AccountListRowDemo = () => {
  const accounts = [{
    domain: "shopify.com",
    name: "Shopify",
    meta: "shopify.com · 12,000 employees"
  }, {
    domain: "stripe.com",
    name: "Stripe",
    meta: "stripe.com · 8,000 employees"
  }, {
    domain: "dropbox.com",
    name: "Dropbox",
    meta: "dropbox.com · 2,600 employees"
  }, {
    domain: "linear.app",
    name: "Linear",
    meta: "linear.app · 60 employees"
  }];
  return <div className="w-full max-w-[360px] flex flex-col gap-0.5">
      {accounts.map(acc => <div key={acc.domain} className="flex items-center gap-3 py-2.5 px-3 rounded-[10px] cursor-pointer transition-colors duration-150 hover:bg-[#6363631f]">
          <img noZoom src={`https://cdn.brandfetch.io/domain/${acc.domain}/w/80/h/80/fallback/lettermark?c=1bfwsmEH20zzEfSNTed`} alt={`${acc.name} logo`} className="w-10 h-10 rounded-lg shrink-0" />
          <div>
            <div className="font-semibold">{acc.name}</div>
            <div className="text-[#6b7280] text-[13px]">{acc.meta}</div>
          </div>
        </div>)}
    </div>;
};

export const Preview = ({children}) => <div className="relative rounded-xl border border-[#63636333] bg-[#6363630d] pt-12 px-8 pb-8 mt-4 mb-4 overflow-hidden">
    <style>{`
      .bf-preview-body img { margin: 0 !important; max-width: none; }
      .bf-preview-body ul, .bf-preview-body ol { margin: 0; padding: 0; }
      .bf-preview-body li { margin: 0 !important; padding-left: 0 !important; }
      .bf-preview-body li::before, .bf-preview-body li::marker { content: none !important; display: none !important; }
      .bf-preview-body p { margin: 0; }
    `}</style>
    <span className="absolute top-3.5 left-[18px] text-[11px] font-semibold tracking-[0.06em] uppercase text-[#636363b3]">
      Preview
    </span>
    <div className="bf-preview-body flex justify-center">{children}</div>
  </div>;

A list full of gray placeholder avatars reads as unfinished. The same list with every company's real logo reads as authoritative, and it's the difference between a text database and a product people trust.

Whether the records are CRM accounts, job listings, or a wall of customer logos, the pattern is the same two tiers: the [Logo API](/logo-api/overview) covers every list view with a plain `<img>` tag, and the [Brand API](/brand-api/overview) fills detail views with colors, descriptions, and firmographics.

## Company directory

CRMs and B2B directories are easier to scan when every account shows the company's real logo instead of a generic placeholder. For a list of accounts, an `<img>` pointed at the Logo API is enough, no fetch, no loading state.

<Tabs>
  <Tab title="Preview">
    <Preview>
      <AccountListRowDemo />
    </Preview>
  </Tab>

  <Tab title="Code">
    ```tsx AccountList.tsx theme={null}
    const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register

    const ACCOUNTS = [
      { domain: "shopify.com", name: "Shopify", meta: "shopify.com · 12,000 employees" },
      { domain: "stripe.com", name: "Stripe", meta: "stripe.com · 8,000 employees" },
      { domain: "dropbox.com", name: "Dropbox", meta: "dropbox.com · 2,600 employees" },
      { domain: "linear.app", name: "Linear", meta: "linear.app · 60 employees" },
    ];

    export function AccountList() {
      return (
        <div className="flex w-full max-w-[360px] flex-col gap-0.5">
          {ACCOUNTS.map((acc) => (
            <div
              key={acc.domain}
              className="flex cursor-pointer items-center gap-3 rounded-[10px] px-3 py-2.5 transition-colors duration-150 hover:bg-[#6363631f]"
            >
              <img
                src={`https://cdn.brandfetch.io/domain/${acc.domain}/w/80/h/80/fallback/lettermark?c=${CLIENT_ID}`}
                alt={`${acc.name} logo`}
                className="h-10 w-10 shrink-0 rounded-lg"
              />
              <div>
                <div className="font-semibold">{acc.name}</div>
                <div className="text-[13px] text-[#6b7280]">{acc.meta}</div>
              </div>
            </div>
          ))}
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

<Prompt description="Want logo-branded account lists in your app? This prompt gives your AI coding tool everything it needs to build it in your framework." actions={["copy", "cursor"]}>
  Build an account list for a CRM or company directory: a vertical list of rows, each showing the company's logo, name, and a secondary line (domain, employee count, etc.) in a compact horizontal layout.

  Fetch each logo via Brandfetch's Logo API `https://cdn.brandfetch.io/domain/{domain}/w/40/h/40/fallback/lettermark?c=YOUR_CLIENT_ID` (get a free client ID at `https://developers.brandfetch.com/register`).

  Add a subtle background color highlight on hover. No fetch or loading state is needed since it's a direct image URL.

  Use the Logo API the intended way: hotlink the CDN URL directly in the image `src`, don't download, cache, or re-host the file. Requests are free with a client ID and always return the brand's current logo.
</Prompt>

## Card grid with hover lift

On grid-based boards, wrap the same data in a card and add a subtle lift on hover so the grid feels responsive to the cursor.

<Tabs>
  <Tab title="Preview">
    <Preview>
      <JobCardGridDemo />
    </Preview>
  </Tab>

  <Tab title="Code">
    ```tsx JobCardGrid.tsx theme={null}
    const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register

    const JOBS = [
      { domain: "dropbox.com", title: "Product Designer", company: "Dropbox · SF" },
      { domain: "vercel.com", title: "DevRel Engineer", company: "Vercel · Remote" },
      { domain: "shopify.com", title: "Growth Marketer", company: "Shopify · NYC" },
      { domain: "stripe.com", title: "Backend Engineer", company: "Stripe · Remote" },
      { domain: "linear.app", title: "Product Manager", company: "Linear · Remote" },
      { domain: "airbnb.com", title: "Data Scientist", company: "Airbnb · Dublin" },
    ];

    export function JobCardGrid() {
      return (
        <div className="grid w-full grid-cols-2 gap-3.5 sm:grid-cols-3">
          {JOBS.map((job) => (
            <div
              key={job.title}
              className="cursor-pointer rounded-xl border border-[#63636333] bg-white p-4 transition duration-150 hover:-translate-y-1 hover:shadow-[0_12px_24px_#0000001f] dark:bg-[#1c1d1f]"
            >
              <img
                src={`https://cdn.brandfetch.io/domain/${job.domain}/w/72/h/72/fallback/lettermark?c=${CLIENT_ID}`}
                alt={`${job.domain} logo`}
                className="h-9 w-9 rounded-lg"
              />
              <div className="mb-0.5 mt-3 text-sm font-semibold">{job.title}</div>
              <div className="text-xs text-[#6b7280]">{job.company}</div>
            </div>
          ))}
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

<Prompt description="Want an animated job card grid in your app? This prompt gives your AI coding tool everything it needs to build it in your framework." actions={["copy", "cursor"]}>
  Build a responsive grid of job cards for a job board.

  Each card shows the employer's logo (fetched via `https://cdn.brandfetch.io/domain/{domain}/w/40/h/40/fallback/lettermark?c=YOUR_CLIENT_ID`, get a free client ID at `https://developers.brandfetch.com/register`), the job title, and company/location.

  Use CSS Grid with `repeat(auto-fill, minmax(220px, 1fr))` for the layout. Add a subtle hover interaction: lift the card 4px with translateY and add a soft box-shadow, animated with a 150ms ease transition.

  Adapt the styling to match my project's existing design system.

  Use the Logo API the intended way: hotlink the CDN URL directly in the image `src`, don't download, cache, or re-host the file. Requests are free with a client ID and always return the brand's current logo.
</Prompt>

## Customer logos

The trick to a tidy wall is a uniform grid: each logo sits centered in an equal-size cell and is capped to the same height, so brands with very different aspect ratios still line up. A fixed column count keeps every row full, no stray logo stranded on its own.

<Tabs>
  <Tab title="Preview">
    <Preview>
      <LogoCloudGridDemo />
    </Preview>
  </Tab>

  <Tab title="Code">
    ```tsx CustomerLogos.tsx theme={null}
    const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register

    const DOMAINS = [
      "airbnb.com", "github.com", "google.com", "intel.com",
      "okta.com", "canva.com", "attio.com", "linkedin.com",
    ];

    export function CustomerLogos() {
      return (
        <div className="grid w-full grid-cols-2 gap-2 sm:grid-cols-4">
          {DOMAINS.map((domain) => (
            <div
              key={domain}
              className="flex h-16 items-center justify-center rounded-xl"
            >
              {/* theme/dark returns the dark-on-light logo; invert it to white in dark mode */}
              <img
                src={`https://cdn.brandfetch.io/domain/${domain}/h/112/w/240/theme/dark/type/logo?c=${CLIENT_ID}`}
                alt={`${domain} logo`}
                className="block max-h-8 w-auto max-w-[60%] object-contain dark:brightness-0 dark:invert"
              />
            </div>
          ))}
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

<Prompt description="Want a customer logo wall (logo grid) in your app? This prompt gives your AI coding tool everything it needs to build it in your framework." actions={["copy", "cursor"]}>
  Build a "trusted by" wall of customer or partner logos as a uniform grid.

  Fetch each logo from Brandfetch's Logo API using the horizontal wordmark variant `https://cdn.brandfetch.io/domain/{domain}/h/56/w/120/type/logo?c=YOUR_CLIENT_ID` (get a free client ID at `https://developers.brandfetch.com/register`).

  Lay them out with CSS Grid using a fixed column count (e.g. 4 columns, responsive down to 2 on mobile) so every row stays full and no logo is left stranded. Give each grid cell a fixed height and center the logo inside it with `object-contain` and a capped max-height/max-width, so brands with different aspect ratios all render at a consistent visual size. Add a subtle hover treatment (a faint background tile). Pick a logo count that fills the grid evenly.

  Use the Logo API the intended way: hotlink the CDN URL directly in the image `src`, don't download, cache, or re-host the file. Requests are free with a client ID and always return the brand's current logo.
</Prompt>

## Animated logos

A 6×3 grid where every tile flips in 3D on its Y axis to reveal a second brand on the back face, staggered on a diagonal so the wall ripples rather than flipping in unison.

<Tabs>
  <Tab title="Preview">
    <Preview>
      <AnimatedFlipWallDemo />
    </Preview>
  </Tab>

  <Tab title="Code">
    ```tsx FlipWall.tsx theme={null}
    const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register

    const POOL = [
      "framer.com", "netflix.com", "airbnb.com", "uber.com", "lyft.com", "doordash.com",
      "tiktok.com", "snapchat.com", "producthunt.com", "reddit.com", "twitch.tv", "linkedin.com",
      "discord.com", "medium.com", "google.com", "microsoft.com", "apple.com", "amazon.com",
      "meta.com", "adobe.com", "salesforce.com", "nvidia.com", "samsung.com", "sony.com",
      "x.com", "slack.com", "vimeo.com", "dribbble.com", "stripe.com", "github.com",
      "gitlab.com", "dropbox.com", "zoom.us", "asana.com", "trello.com", "atlassian.com",
    ];

    const src = (d: string) =>
      `https://cdn.brandfetch.io/domain/${d}/type/icon/w/112/h/112/fallback/lettermark?c=${CLIENT_ID}`;

    export function FlipWall() {
      const tiles = Array.from({ length: 18 }, (_, i) => {
        const row = Math.floor(i / 6);
        const col = i % 6;
        return { a: POOL[i], b: POOL[i + 18], d: -((row + col) * 0.35), i };
      });

      return (
        <div className="grid gap-6" style={{ gridTemplateColumns: "repeat(6, 44px)" }}>
          <style>{`
            @keyframes bf-flip {
              0%, 42%  { transform: rotateY(0deg); }
              50%, 92% { transform: rotateY(180deg); }
              100%     { transform: rotateY(360deg); }
            }
          `}</style>
          {tiles.map(({ a, b, d, i }) => (
            <div key={i} style={{ perspective: "700px" }} className="h-11 w-11">
              <div
                className="relative h-full w-full"
                style={{
                  transformStyle: "preserve-3d",
                  animationName: "bf-flip",
                  animationDuration: "6s",
                  animationTimingFunction: "ease-in-out",
                  animationIterationCount: "infinite",
                  animationDelay: `${d}s`,
                }}
              >
                <img src={src(a)} alt={a} className="absolute inset-0 h-full w-full rounded-xl object-contain" style={{ backfaceVisibility: "hidden", WebkitBackfaceVisibility: "hidden" }} />
                <img src={src(b)} alt={b} className="absolute inset-0 h-full w-full rounded-xl object-contain" style={{ backfaceVisibility: "hidden", WebkitBackfaceVisibility: "hidden", transform: "rotateY(180deg)" }} />
              </div>
            </div>
          ))}
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

<Prompt description="Want an animated logo grid that 3D-flips between brands? This prompt gives your AI coding tool everything it needs to build it in your framework." actions={["copy", "cursor"]}>
  Build an animated logo wall as a grid (e.g. 6×3) of square icon tiles that flip in 3D to reveal a second brand, so the wall shows twice as many brands as it has slots. Each tile is a card with a front face (brand A) and a back face (brand B) that rotates on its Y axis.

  Set `perspective` on the tile wrapper, `transform-style: preserve-3d` on the rotating inner element, and `backface-visibility: hidden` on both faces (the back face pre-rotated `rotateY(180deg)`). Animate the inner element's `rotateY` with a CSS `@keyframes` (0° → 180° → 360°, with holds so each face stays readable), and stagger the `animation-delay` by grid position (row + column) so the flips ripple diagonally across the wall.

  Render each face from Brandfetch's Logo API `icon` variant: `https://cdn.brandfetch.io/domain/{domain}/type/icon/w/56/h/56/fallback/lettermark?c=YOUR_CLIENT_ID` (get a free client ID at `https://developers.brandfetch.com/register`). Use `fallback/lettermark` so a tile never shows a broken image.

  Use the Logo API the intended way: hotlink the CDN URL directly in the image `src`, don't download, cache, or re-host the file. Requests are free with a client ID and always return the brand's current logo.
</Prompt>

## Infinite scroll marquee

An auto-scrolling row loops seamlessly, letting you show two or three times as many logos in the same footprint, useful for long partner lists. Using the square `icon` variant keeps every mark colorful and the same size, so the row reads as one clean band.

<Tabs>
  <Tab title="Preview">
    <Preview>
      <AnimatedMarqueeDemo />
    </Preview>
  </Tab>

  <Tab title="Code">
    ```tsx LogoMarquee.tsx theme={null}
    const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register

    const DOMAINS = [
      "shopify.com", "airbnb.com", "nike.com", "discord.com", "slack.com",
      "stripe.com", "dropbox.com", "reddit.com", "medium.com", "meta.com",
    ];

    export function LogoMarquee() {
      const track = [...DOMAINS, ...DOMAINS]; // duplicate so the loop has no seam

      return (
        <div className="bf-marquee-fade w-full max-w-[520px] overflow-hidden">
          <style>{`
            .bf-marquee-fade { -webkit-mask-image: linear-gradient(to right, transparent, black 12%, black 88%, transparent); mask-image: linear-gradient(to right, transparent, black 12%, black 88%, transparent); }
            .bf-marquee-track { animation: bf-scroll 22s linear infinite; }
            .bf-marquee:hover .bf-marquee-track { animation-play-state: paused; }
            @keyframes bf-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
          `}</style>
          <div className="bf-marquee">
            <div className="bf-marquee-track flex w-max items-center gap-6 py-2">
              {track.map((domain, i) => (
                <img
                  key={i}
                  src={`https://cdn.brandfetch.io/domain/${domain}/type/icon/w/80/h/80/fallback/lettermark?c=${CLIENT_ID}`}
                  alt={`${domain} logo`}
                  className="h-10 w-10 shrink-0 rounded-xl"
                />
              ))}
            </div>
          </div>
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

<Prompt description="Want an auto-scrolling logo marquee in your app? This prompt gives your AI coding tool everything it needs to build it in your framework." actions={["copy", "cursor"]}>
  Build an auto-scrolling logo marquee that loops seamlessly.

  Render a row of partner logos twice back-to-back (so the loop has no visible seam), each fetched as a square `icon` from `https://cdn.brandfetch.io/domain/{domain}/type/icon/w/80/h/80/fallback/lettermark?c=YOUR_CLIENT_ID` (get a free client ID at `https://developers.brandfetch.com/register`). Icons are colorful and all the same size, so the band stays even and vivid.

  Animate the track horizontally from `translateX(0)` to `translateX(-50%)` on an infinite linear loop (about 15-25s), pause the animation on hover, and fade the edges with a `mask-image` gradient so logos don't appear abruptly.

  Use the Logo API the intended way: hotlink the CDN URL directly in the image `src`, don't download, cache, or re-host the file. Requests are free with a client ID and always return the brand's current logo.
</Prompt>

## Inline logo swap

A single rotating slot works inline too, drop it into a headline or a "trusted by" line to cycle a marquee brand through the sentence.

<Tabs>
  <Tab title="Preview">
    <Preview>
      <AnimatedLogoSwapDemo />
    </Preview>
  </Tab>

  <Tab title="Code">
    ```tsx InlineLogoSwap.tsx theme={null}
    const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register

    const DOMAINS = ["airbnb.com", "slack.com", "discord.com", "linear.app", "stripe.com"];

    const src = (d: string) =>
      `https://cdn.brandfetch.io/domain/${d}/type/icon/w/96/h/96/fallback/lettermark?c=${CLIENT_ID}`;

    export function InlineLogoSwap() {
      return (
        <div className="flex items-center gap-3 text-lg font-medium">
          <style>{`
            @keyframes bf-logocycle {
              0%   { opacity: 1; transform: scale(1); }
              15%  { opacity: 1; transform: scale(1); }
              20%  { opacity: 0; transform: scale(0.9); }
              95%  { opacity: 0; transform: scale(0.9); }
              100% { opacity: 1; transform: scale(1); }
            }
          `}</style>
          <span>Trusted by</span>
          <span className="relative inline-block h-9 w-9 align-middle">
            {DOMAINS.map((d, i) => (
              <img
                key={d}
                src={src(d)}
                alt={d}
                className="absolute inset-0 h-9 w-9 rounded-lg object-contain"
                style={{
                  animationName: "bf-logocycle",
                  animationDuration: "10s",
                  animationTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
                  animationIterationCount: "infinite",
                  animationDelay: `${-(i * 2)}s`,
                }}
              />
            ))}
          </span>
          <span>and 20,000+ teams</span>
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

<Prompt description="Want an inline logo that rotates through brands inside a headline? This prompt gives your AI coding tool everything it needs to build it in your framework." actions={["copy", "cursor"]}>
  Build an inline animated logo slot that rotates through several company icons, sized to sit inside a line of text (e.g. "Trusted by \[logo] and 20,000+ teams").

  Stack the icons absolutely in a small fixed-size inline-block span and crossfade them with a CSS `@keyframes` animation. With N icons, give each the same keyframe (visible for \~1/N of the cycle, then hidden) and offset each one's `animation-delay` by cycle/N so they rotate one after another. Fetch each icon from `https://cdn.brandfetch.io/domain/{domain}/type/icon/w/48/h/48/fallback/lettermark?c=YOUR_CLIENT_ID` (get a free client ID at `https://developers.brandfetch.com/register`).

  Use the Logo API the intended way: hotlink the CDN URL directly in the image `src`, don't download, cache, or re-host the file. Requests are free with a client ID and always return the brand's current logo.
</Prompt>

## Implementation

<Steps>
  <Step title="Key every record by domain">
    The domain is the identifier that makes everything else work. If your data only has company names, match them to domains first with the [Brand Search API](/brand-search-api/overview).
  </Step>

  <Step title="Lists: Logo API">
    For rows, cards, and avatars, point an `<img>` at the CDN, no fetch, no loading state, and `fallback/lettermark` guarantees a clean monogram for brands not yet in the dataset.

    ```text theme={null}
    https://cdn.brandfetch.io/domain/{domain}/w/40/h/40/fallback/lettermark?c=YOUR_CLIENT_ID
    ```
  </Step>

  <Step title="Detail views: Brand API">
    When a user opens a record, fetch the full brand server-side for the description, accent color, and firmographics, and cache it by domain so repeat visits are free.

    ```bash theme={null}
    curl "https://api.brandfetch.io/v2/brands/domain/stripe.com" \
      --header "Authorization: Bearer YOUR_API_KEY"
    ```
  </Step>
</Steps>

## Pricing

List views cost nothing, the [Logo API](/logo-api/overview) is free with a client ID. Detail views cost one Brand API brand fetch per company, and domain-level caching means each company is fetched once, not once per viewer. See [plans](https://brandfetch.com/developers/pricing) for quotas.

## Going further

<CardGroup cols={3}>
  <Card title="Logo API parameters" icon="sliders" href="/logo-api/parameters">
    Sizing, type, theme, and fallback options for every logo.
  </Card>

  <Card title="Brand API reference" icon="code" href="/reference/brand-api-domain">
    The full record: logos, colors, images, and firmographics for detail views.
  </Card>

  <Card title="Get started" icon="rocket" href="https://developers.brandfetch.com/register">
    Create a free account and start building.
  </Card>
</CardGroup>
