Skip to content
Facade UI
Colour mode
GitHub (opens in a new tab)
blocksection

Logo cloud

A wall of customer logos. Company names are exposed as text, so it reads as a list rather than a run of unlabelled images.

Also ships a motion variant: Logo cloud (motion). The static one is the default.

Preview

Open full width (opens in a new tab)
Preview width

Installation

Package manager
pnpm dlx shadcn@latest add https://facadeui.dev/r/logo-cloud.json

Pulls in container, logo-mark, section, section-header, types, utils. The CLI installs them for you.

Usage

The exact source of the preview above.

demos/logo-cloud.tsx
import { LogoCloud } from "@registry/sections/logo-cloud"

import { LOGOS } from "./content"

export function Demo() {
  return <LogoCloud title="Trusted by teams shipping every day" items={LOGOS} showNames />
}

Source

What the CLI copies into your project, byte for byte.

components/sections/logo-cloud.tsx
/**
 * LogoCloud — a wall of customer or partner logos.
 *
 * Content-driven: pass `items` and, if you use `next/image` or `next/link`, pass
 * those components. The section itself imports no framework.
 *
 * a11y: the logos are a `<ul>`, because that is what they are — a list of
 * companies. Each `LogoMark` exposes its company name as text (visually hidden
 * unless `showNames`), so the wall reads as "Northwind, Contoso, …" instead of a
 * run of unlabelled images. When `title` is omitted the band renders as a `div`
 * rather than adding an unnamed region to the landmark list.
 *
 * Dependencies: react, @/lib/types, @/lib/utils,
 * @/components/ui/container, @/components/ui/logo-mark, @/components/ui/section,
 * @/components/ui/section-header.
 */

import type { ElementType } from "react"

import type {
  ImageComponent,
  LinkComponent,
  ListSlotProps,
  SectionBaseProps,
} from "@/lib/types"
import { cn, slugId } from "@/lib/utils"
import { Container } from "@/components/ui/container"
import { LogoMark, type LogoItem } from "@/components/ui/logo-mark"
import { Section } from "@/components/ui/section"
import { SectionHeader } from "@/components/ui/section-header"

export interface LogoCloudProps extends SectionBaseProps, ListSlotProps {
  items: LogoItem[]
  /** Optional heading. Omit for a bare strip under a hero. */
  title?: string
  eyebrow?: string
  description?: string
  image?: ImageComponent
  link?: LinkComponent
  /** Rendered logo height. */
  size?: "sm" | "md" | "lg"
  /** Show each company name as text beside its mark. */
  showNames?: boolean
  /** `row` wraps on one line; `grid` gives every logo equal width. */
  layout?: "row" | "grid"
  /** Desaturate and fade logos until hover or focus. */
  muted?: boolean
}

export function LogoCloud({
  items,
  title,
  eyebrow,
  description,
  image,
  link,
  size = "md",
  showNames = false,
  layout = "row",
  muted = true,
  listAs,
  itemAs,
  headingLevel = 2,
  as,
  spacing = "sm",
  className,
  id,
}: LogoCloudProps) {
  const List = (listAs ?? "ul") as ElementType
  const Item = (itemAs ?? "li") as ElementType
  const titleId = title ? (id ? `${id}-title` : slugId(title)) : undefined

  return (
    <Section
      as={as ?? (title ? "section" : "div")}
      spacing={spacing}
      labelledBy={titleId}
      id={id}
      className={className}
    >
      <Container className="flex flex-col gap-10">
        {title ? (
          <SectionHeader
            align="center"
            size="sm"
            eyebrow={eyebrow}
            title={title}
            description={description}
            headingLevel={headingLevel}
            titleId={titleId}
          />
        ) : null}

        <List
          className={cn(
            layout === "row"
              ? "flex flex-wrap items-center justify-center gap-x-10 gap-y-8 sm:gap-x-14"
              : "grid grid-cols-2 items-center justify-items-center gap-8 sm:grid-cols-3 lg:grid-cols-5",
          )}
        >
          {items.map((item) => (
            <Item key={item.name}>
              <LogoMark
                {...item}
                image={image}
                link={link}
                size={size}
                muted={muted}
                showName={showNames}
              />
            </Item>
          ))}
        </List>
      </Container>
    </Section>
  )
}

Props

LogoCloudProps

Extends SectionBaseProps, ListSlotProps.

Props for LogoCloudProps
PropTypeDefault
items*RequiredLogoItem[]
titleOptional heading. Omit for a bare strip under a hero.string
eyebrowstring
descriptionstring
imageImageComponent
linkLinkComponent
sizeRendered logo height."sm" | "md" | "lg""md"
showNamesShow each company name as text beside its mark.booleanfalse
layout`row` wraps on one line; `grid` gives every logo equal width."row" | "grid""row"
mutedDesaturate and fade logos until hover or focus.booleantrue