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

> 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é](https://clearlogo.dev/login?lang=fr) depuis le tableau de bord.

## 1. HTML simple

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

```html
<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.

```tsx
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.

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

```tsx
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.

```tsx
<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.

```html
<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 :

```tsx
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.

```tsx
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.

```tsx
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.

```ts
// 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.

```ts
// 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.

```ts
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.

```html
<link rel="preconnect" href="https://api.clearlogo.dev" crossorigin />
<link rel="dns-prefetch" href="https://api.clearlogo.dev" />
```

```tsx
// 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.

### Comment afficher un fallback quand l'API ne retourne pas de logo ?

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