Retour

Livre de recettes d'intégration

Déposez un logo d'entreprise dans votre app — recettes prêtes à copier-coller

Extraits prêts pour la production pour ajouter des logos d'entreprise à votre interface utilisateur, d'une simple balise img à React, Next.js Image, avatars Tailwind, gestion du mode sombre, fallbacks OG et signature côté serveur.

Extraits pratiques pour les formes courantes dans lesquelles un logo finit : une balise <img>, un composant React, une Image Next.js, un emplacement d'avatar Tailwind, un élément <picture> conscient du mode sombre, un fallback d'image OG et une URL signée côté serveur. Chaque extrait fonctionne avec le point de terminaison public https://api.clearlogo.dev.

Tous les exemples supposent que vous disposez d'une clé navigateur (pour le code client) ou d'une clé serveur (pour le code backend). Créez une clé depuis le tableau de bord.

1. HTML simple

Intégration aussi rapide que possible — collez l'URL dans une balise <img>.

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

Définissez size pour correspondre à la dimension rendue afin que le navigateur ne gaspille pas la bande passante en redimensionnant une ressource plus grande.

2. Composant React

Un petit composant réutilisable couvre la plupart des besoins de l'interface utilisateur du produit.

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" et decoding="async" empêchent les longues listes de bloquer l'affichage.

3. Next.js <Image>

Ajoutez l'hôte de l'API à next.config.js une fois, puis utilisez le composant <Image> optimisé partout.

// 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
    />
  );
}

Demandez size * 2 pour la netteté retina sur les écrans HiDPI. Utilisez unoptimized si vous voulez que la négociation WebP de l'API s'effectue jusqu'au client.

4. Emplacement d'avatar Tailwind

Déposez le logo dans un emplacement d'interface utilisateur fixe qui reste visuellement cohérent selon les marques.

<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 plus une taille d'emplacement fixe est la forme la plus fiable pour les tableaux et les listes. Associez-le au paramètre content=80 pour que le logo ne s'appuie jamais contre le bord de l'emplacement.

5. Logo conscient du mode sombre

Utilisez <picture> avec une source prefers-color-scheme pour que le navigateur échange la variante sombre au moment du rendu — pas de JavaScript, pas de rerenders.

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

Enveloppé comme un composant 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>
  );
}

L'API revient à la variante claire quand aucune version sombre n'existe, donc il est toujours sûr de demander theme=dark.

6. Rendu de liste avec un placeholder

Pour les longues listes, rendez un placeholder immédiat pour que les emplacements vides ne clignotent pas.

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>
  );
}

Le fond neutre remplit l'emplacement instantanément, et le logo se fond quand il est décodé.

7. Fallback d'erreur avec la première lettre

Si l'API ne trouve pas de logo pour un domaine, rendez un avatar lettre déterministe à la place.

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)}
    />
  );
}

Le fallback ne fait jamais de requête réseau, donc même les lignes froides restent rapides.

8. Fallback d'image Open Graph

Utilisez une récupération côté serveur pour intégrer un logo dans votre propre carte OG générée dynamiquement.

// 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 },
  );
}

Utilisez une clé de serveur ici, pas une clé navigateur — les Edge functions sont côté serveur.

9. Signature backend pour les interfaces utilisateur sensibles

Quand vous ne voulez pas que l'URL soit publique (p. ex. outils d'administration interne), passez par votre 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",
    },
  });
}

Maintenant votre frontend utilise /api/logo/{domain} — pas de clé API dans la source de la page, et vous contrôlez la mise en cache à votre propre CDN.

10. Assistant TypeScript

Un seul assistant garde la construction d'URL cohérente dans la base de code.

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 protège contre les caractères inhabituels dans les domaines et rend l'assistant sûr à appeler avec une entrée non fiable.

11. Préconnexion pour réchauffer la connexion tôt

Pour les tableaux de bord qui rendent des dizaines de logos au-dessus de la ligne de flottaison, la première requête paie pour DNS, TCP et TLS. Ajoutez un seul <link rel="preconnect"> à l'en-tête de votre document pour que la connexion soit prête avant que le premier <img> ne se déclenche.

<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 résout DNS et ouvre la poignée de main TCP/TLS immédiatement ; dns-prefetch est un fallback bon marché pour les navigateurs qui ignorent la préconnexion.

FAQ

Par quelle recette devrais-je commencer ?

Si vous rendez un seul logo, la recette simple <img> est suffisante. Pour les listes et les tableaux, passez à l'emplacement d'avatar Tailwind et le modèle de chargement paresseux.

Ai-je besoin d'une clé pour les tests ?

Non. Le point de terminaison fonctionne anonymement pour le navigateur à faible volume. Ajoutez une clé navigateur avant de passer en production pour que la requête soit correctement attribuée et comptabilisée selon votre plan.

Quelle taille devrais-je demander ?

Faites correspondre la taille rendue en CSS, puis demandez 2x cela pour la netteté retina. Ne demandez pas 1024 pour un emplacement de 32 pixels — cela coûte de la bande passante et ne semble pas mieux.

Comment gérer le mode sombre sans JavaScript ?

Utilisez un élément <picture> avec une source <source> bloquée par media="(prefers-color-scheme: dark)". Le navigateur choisit l'URL correcte au moment du rendu.

Comment faire charger une liste de logos plus rapidement ?

Ajoutez un seul <link rel="preconnect" href="https://api.clearlogo.dev"> dans l'en-tête de votre document. Cela ouvre DNS/TCP/TLS une fois pour chaque logo de la page.

Écoutez onError sur <img> et échangez un avatar lettre ou une icône générique. La recette de fallback d'erreur ci-dessus est la forme de production.

Puis-je utiliser une clé navigateur à partir d'un rendu côté serveur ?

Vous le pouvez — mais une clé serveur est un meilleur ajustement car elle envoie la requête via Authorization: Bearer … plutôt que de compter sur des vérifications d'origine.

Comment mettre en cache les logos à mon propre CDN ?

Utilisez la recette de signature backend ci-dessus. La réponse en amont inclut un Cache-Control de longue durée, vous pouvez donc définir les mêmes en-têtes sur votre proxy.

Essayez un domaine réel dans le terrain de jeu

Une fois que la forme de la recette semble correcte, échangez quelques-uns de vos propres domaines de clients ou de partenaires et prévisualisez le résultat avant de l'expédier.