Atrás

Libro de recetas de integración

Suelta un logotipo de empresa en tu aplicación — recetas de copiar y pegar

Fragmentos listos para producción para agregar logotipos de empresas a tu UI, desde una etiqueta img simple hasta React, Next.js Image, avatares Tailwind, manejo de modo oscuro, respaldos OG y firma del lado del servidor.

Fragmentos prácticos para las formas comunes en que un logotipo termina: una etiqueta <img>, un componente React, una Next.js Image, una ranura de avatar Tailwind, un elemento <picture> consciente del modo oscuro, un respaldo de imagen OG y una URL firmada del servidor. Cada fragmento funciona contra el endpoint público https://api.clearlogo.dev.

Todos los ejemplos asumen que tienes una clave de navegador (para código de cliente) o una clave de servidor (para código de backend). Crea una clave desde el dashboard.

1. HTML simple

Integración más rápida posible — pega la URL en una etiqueta <img>.

<img
  src="https://api.clearlogo.dev/logo/github.com?size=64&content=80&token=YOUR_BROWSER_KEY"
  alt="GitHub"
  width="64"
  height="64"
/>

Establece size para que coincida con la dimensión renderizada para que el navegador no desperdicie ancho de banda escalando un activo más grande.

2. Componente React

Un pequeño componente reutilizable cubre la mayoría de las necesidades de interfaz de usuario del producto.

type CompanyLogoProps = {
  domain: string;
  size?: 32 | 48 | 64 | 96 | 128;
  alt?: string;
};

const BROWSER_KEY = process.env.NEXT_PUBLIC_CLEARLOGO_KEY!;

export function CompanyLogo({ domain, size = 64, alt }: CompanyLogoProps) {
  return (
    <img
      src={`https://api.clearlogo.dev/logo/${domain}?size=${size}&content=80&token=${BROWSER_KEY}`}
      alt={alt ?? `${domain} logo`}
      width={size}
      height={size}
      loading="lazy"
      decoding="async"
    />
  );
}

loading="lazy" y decoding="async" mantienen listas largas (CRM, directorios, tablas de cuentas) de bloquear la pintura.

3. Next.js <Image>

Agrega el host de la API a next.config.js una sola vez, luego usa el componente <Image> optimizado en todas partes.

// next.config.js
module.exports = {
  images: {
    remotePatterns: [
      { protocol: "https", hostname: "api.clearlogo.dev" },
    ],
  },
};
import Image from "next/image";

export function CompanyLogo({ domain, size = 64 }: { domain: string; size?: number }) {
  return (
    <Image
      src={`https://api.clearlogo.dev/logo/${domain}?size=${size * 2}&content=80&token=${process.env.NEXT_PUBLIC_CLEARLOGO_KEY}`}
      alt={`${domain} logo`}
      width={size}
      height={size}
      unoptimized
    />
  );
}

Solicita size * 2 para nitidez retina en pantallas HiDPI. Usa unoptimized si deseas que la negociación WebP de la API fluya hacia el cliente; elimínalo si deseas que Next.js maneje la negociación de formato en sí.

4. Ranura de avatar Tailwind

Suelta el logotipo en una ranura de UI fija que se mantiene visualmente consistente en todas las marcas.

<div className="flex items-center gap-3">
  <div className="h-10 w-10 overflow-hidden rounded-md bg-neutral-100 ring-1 ring-neutral-200">
    <img
      src={`https://api.clearlogo.dev/logo/${domain}?size=64&content=80&token=${BROWSER_KEY}`}
      alt=""
      className="h-full w-full object-contain"
    />
  </div>
  <div>
    <div className="font-medium">{name}</div>
    <div className="text-sm text-neutral-500">{domain}</div>
  </div>
</div>

object-contain más un tamaño de ranura fijo es la forma más confiable para tablas y listas. Empareja con el parámetro content=80 para que el logotipo nunca llegue al borde de la ranura.

5. Logotipo consciente del modo oscuro

Usa <picture> con prefers-color-scheme para cambiar variantes oscuro/claro en tiempo de pintura, sin JavaScript o rerenders por logotipo.

<picture>
  <source
    srcset="https://api.clearlogo.dev/logo/github.com?size=64&theme=dark&token=YOUR_BROWSER_KEY"
    media="(prefers-color-scheme: dark)"
  />
  <img
    src="https://api.clearlogo.dev/logo/github.com?size=64&theme=light&token=YOUR_BROWSER_KEY"
    alt="GitHub"
    width="64"
    height="64"
  />
</picture>

Envuelto como un componente React:

export function CompanyLogo({ domain, size = 64 }: { domain: string; size?: number }) {
  const base = `https://api.clearlogo.dev/logo/${domain}?size=${size}&content=80&token=${BROWSER_KEY}`;
  return (
    <picture>
      <source srcSet={`${base}&theme=dark`} media="(prefers-color-scheme: dark)" />
      <img src={`${base}&theme=light`} alt={`${domain} logo`} width={size} height={size} />
    </picture>
  );
}

La API vuelve a la variante clara cuando no existe una versión oscura, así que siempre es seguro solicitar theme=dark. Para cambios de tema a nivel de aplicación (no a nivel del sistema operativo), controla la URL de origen desde tu estado de tema en lugar de prefers-color-scheme.

6. Renderizado de lista con un marcador de posición

Para listas largas, renderiza un marcador de posición inmediato para que las ranuras vacías no parpadeen.

function LogoCell({ domain }: { domain: string }) {
  const [loaded, setLoaded] = useState(false);
  return (
    <div className="relative h-10 w-10 rounded-md bg-neutral-100">
      <img
        src={`https://api.clearlogo.dev/logo/${domain}?size=64&content=80&token=${BROWSER_KEY}`}
        alt=""
        loading="lazy"
        onLoad={() => setLoaded(true)}
        className={`h-full w-full object-contain transition-opacity ${
          loaded ? "opacity-100" : "opacity-0"
        }`}
      />
    </div>
  );
}

El fondo neutral llena la ranura al instante, y el logotipo se desvanece una vez decodificado.

7. Respaldo de error con la primera letra

Si la API no puede encontrar un logotipo para un dominio, renderiza un avatar de letra determinista en su lugar.

function LogoOrFallback({ domain, name }: { domain: string; name: string }) {
  const [errored, setErrored] = useState(false);

  if (errored) {
    return (
      <div className="flex h-10 w-10 items-center justify-center rounded-md bg-neutral-200 font-medium text-neutral-600">
        {name[0]?.toUpperCase() ?? "?"}
      </div>
    );
  }

  return (
    <img
      src={`https://api.clearlogo.dev/logo/${domain}?size=64&content=80&token=${BROWSER_KEY}`}
      alt={`${name} logo`}
      width={40}
      height={40}
      className="rounded-md"
      onError={() => setErrored(true)}
    />
  );
}

El respaldo nunca realiza una solicitud de red, así que incluso las filas frías se mantienen rápidas.

8. Respaldo de imagen Open Graph

Utiliza una búsqueda del lado del servidor para incrustar un logotipo en tu propia tarjeta OG generada dinámicamente.

// app/og/route.ts (Next.js, Edge runtime)
import { ImageResponse } from "next/og";

export const runtime = "edge";

export async function GET(request: Request) {
  const { searchParams } = new URL(request.url);
  const domain = searchParams.get("domain") ?? "example.com";

  const logoUrl = `https://api.clearlogo.dev/logo/${domain}?size=256&content=80&token=YOUR_SERVER_KEY`;

  return new ImageResponse(
    (
      <div style={{ display: "flex", alignItems: "center", padding: 64 }}>
        <img src={logoUrl} width={128} height={128} alt="" />
        <span style={{ marginLeft: 32, fontSize: 64 }}>{domain}</span>
      </div>
    ),
    { width: 1200, height: 630 },
  );
}

Usa una clave de servidor aquí, no una clave de navegador — Las funciones Edge son del lado del servidor, y una clave de servidor es lo que sobrevive a encabezados de origen sin restricciones.

9. Firma del backend para interfaces UI sensibles

Cuando no deseas que la URL sea pública (p. ej. herramientas administrativas internas), procesa a través de tu backend.

// app/api/logo/[domain]/route.ts (Next.js)
export async function GET(
  request: Request,
  { params }: { params: { domain: string } },
) {
  const upstream = await fetch(
    `https://api.clearlogo.dev/logo/${params.domain}?size=128&content=80`,
    { headers: { Authorization: `Bearer ${process.env.CLEARLOGO_SERVER_KEY}` } },
  );
  return new Response(upstream.body, {
    headers: {
      "Content-Type": upstream.headers.get("Content-Type") ?? "image/png",
      "Cache-Control": "public, max-age=86400, s-maxage=86400",
    },
  });
}

Sin clave de API en el origen de la página, y controlas el almacenamiento en caché en tu propio CDN.

10. Asistente de TypeScript

Un único asistente mantiene la construcción de URL consistente en toda la base de código.

type LogoOptions = {
  size?: 16 | 32 | 48 | 64 | 96 | 128 | 192 | 256 | 512 | 1024;
  content?: number; // 50–100, step 5
  theme?: "light" | "dark";
  format?: "png" | "webp" | "jpeg";
};

export function logoUrl(domain: string, opts: LogoOptions = {}): string {
  const params = new URLSearchParams({
    size: String(opts.size ?? 64),
    content: String(opts.content ?? 80),
    token: process.env.NEXT_PUBLIC_CLEARLOGO_KEY!,
  });
  if (opts.theme) params.set("theme", opts.theme);
  if (opts.format) params.set("format", opts.format);
  return `https://api.clearlogo.dev/logo/${encodeURIComponent(domain)}?${params}`;
}

encodeURIComponent protege contra caracteres inusuales en dominios y hace que el asistente sea seguro para llamar con entrada no confiable.

11. Preconectarse para calentar la conexión temprano

Para dashboards que renderizan docenas de logotipos encima de la carpeta, la primera solicitud paga por DNS, TCP y TLS. Agrega un único <link rel="preconnect"> al encabezado de tu documento para que la conexión esté lista antes de que el primer <img> se active — cada logotipo posterior obtiene una ventaja sin la masa de precargas por URL.

<link rel="preconnect" href="https://api.clearlogo.dev" crossorigin />
<link rel="dns-prefetch" href="https://api.clearlogo.dev" />
// Next.js
import Head from "next/head";

export function ClearLogoPreconnect() {
  return (
    <Head>
      <link rel="preconnect" href="https://api.clearlogo.dev" crossOrigin="" />
      <link rel="dns-prefetch" href="https://api.clearlogo.dev" />
    </Head>
  );
}

preconnect resuelve DNS y abre el apretón de manos TCP/TLS inmediatamente; dns-prefetch es un respaldo económico para navegadores que ignoran la preconexión. Dos sugerencias totales, sin importar cuántos logotipos renderice la página. Prefiere esto sobre <link rel="preload" as="image"> por logotipo — las precargas son pesadas, cuentan hacia presupuestos de ancho de banda, y no ayudan si la URL renderizada termina siendo ligeramente diferente (tamaño, tema, token) de la precargada.

FAQ

¿Con cuál receta debo empezar?

Para un único logotipo, la receta <img> simple es suficiente. Para listas y tablas, salta a la ranura de avatar Tailwind y al patrón de carga perezosa.

¿Necesito una clave para probar?

No. El endpoint funciona anónimamente para navegación de bajo volumen. Agrega una clave de navegador antes de que envíes a producción para que la solicitud sea debidamente atribuida y contada contra tu plan.

¿Qué tamaño debo solicitar?

Coincide el tamaño renderizado en CSS, luego solicita 2x eso para nitidez retina. No solicites 1024 para una ranura de 32 píxeles — cuesta ancho de banda y no se ve mejor.

¿Cómo manejo el modo oscuro sin JavaScript?

Usa un elemento <picture> con una <source> restringida por media="(prefers-color-scheme: dark)". El navegador elige la URL correcta en tiempo de pintura — no hook React, no rerender por logotipo, no gastos generales por fila incluso en listas largas.

¿Cómo hago que una lista de logotipos se cargue más rápido?

Agrega un único <link rel="preconnect" href="https://api.clearlogo.dev"> en el encabezado de tu documento. Eso abre DNS/TCP/TLS una sola vez para cada logotipo en la página, que es más económico que <link rel="preload"> por URL.

¿Cómo muestro un respaldo cuando la API no devuelve un logotipo?

Escucha onError en el <img> e intercambia por un avatar de letra o un icono genérico. La receta de respaldo de error anterior es la forma de producción.

¿Puedo usar una clave de navegador desde una renderización del lado del servidor?

Puedes — pero una clave de servidor es un mejor ajuste porque envía la solicitud vía Authorization: Bearer … en lugar de depender de controles de origen. Para Componentes de Servidor de Next.js, rutas OG, o proxies de backend, usa una clave de servidor.

¿Cómo almaceno logotipos en caché en mi propio CDN?

Utiliza la receta de firma de backend anterior. La respuesta ascendente incluye Cache-Control de larga duración, para que puedas establecer los mismos encabezados en tu proxy y dejar que tu CDN haga el resto.

Prueba un dominio real en el área de juegos

Una vez que la forma de la receta se vea correcta, cambia algunos de tus propios dominios de clientes o socios y ve una vista previa del resultado antes de enviarlo.