
# أسقط شعار الشركة في تطبيقك — وصفات نسخ لصق

> مقاطع عملية للأشكال الشائعة التي ينتهي الشعار فيها: علامة `<img>`، مكون React، صورة Next.js، فتحة Tailwind avatar، عنصر `<picture>` موجه للوضع المظلم، ملجأ صورة OG، وعنوان URL موقع من جانب الخادم. كل مقطع يعمل مقابل نقطة نهاية `https://api.clearlogo.dev` العامة.
>
> جميع الأمثلة تفترض أن لديك مفتاح متصفح (لكود جانب العميل) أو مفتاح خادم (لكود جانب الخادم). [أنشئ مفتاحاً](https://clearlogo.dev/login?lang=ar) من لوحة التحكم.

## 1. HTML عادي

أسرع تكامل ممكن — الصق عنوان URL في علامة `<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"
/>
```

اضبط `size` ليطابق البعد المعروض حتى لا يضيع المتصفح النطاق الترددي في تحجيم أصل أكبر.

## 2. مكون React

مكون قابل لإعادة الاستخدام صغير يغطي معظم احتياجات واجهة المستخدم للمنتج.

```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"` و `decoding="async"` يمنعان القوائم الطويلة (CRMs والدلائل وجداول الحسابات) من منع الطلاء.

## 3. Next.js `<Image>`

أضف مضيف API إلى `next.config.js` مرة واحدة، ثم استخدم مكون `<Image>` المحسّن في كل مكان.

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

اطلب `size * 2` لحدة HiDPI على الشاشات ذات الدقة العالية. استخدم `unoptimized` إذا كنت تريد من مفاوضة WebP من واجهة برمجة التطبيقات أن تتدفق إلى العميل؛ أزله إذا كنت تريد من Next.js أن يتعامل مع مفاوضة الشكل نفسه.

## 4. فتحة Tailwind avatar

أسقط الشعار في فتحة واجهة مستخدم ثابتة التي تبقى متسقة بصرياً عبر العلامات التجارية.

```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` بالإضافة إلى حجم فتحة ثابت هو الشكل الأكثر موثوقية للجداول والقوائم. اجمع مع معامل `content=80` حتى لا يصطدم الشعار بحافة الفتحة.

## 5. شعار موجه للوضع المظلم

استخدم `<picture>` مع `prefers-color-scheme` لتبديل متغيرات داكنة/خفيفة في وقت الطلاء، بدون JavaScript أو إعادة عرض لكل شعار.

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

ملفوفة كمكون 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>
  );
}
```

واجهة برمجة التطبيقات تعود إلى متغير الإضاءة عندما لا يوجد نسخة مظلمة، لذا يكون طلب `theme=dark` دائماً آمناً. لمفاتيح الموضوع على مستوى التطبيق (وليس مستوى نظام التشغيل)، قم بتشغيل عنوان URL المصدر من حالة الموضوع الخاصة بك بدلاً من `prefers-color-scheme`.

## 6. قائمة الرسم مع جزء عام

للقوائم الطويلة، قم برسم جزء عام فوري حتى لا تومض الفتحات الفارغة.

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

## 7. ملجأ الخطأ مع الحرف الأول

إذا لم تتمكن واجهة برمجة التطبيقات من العثور على شعار لنطاق، قم برسم دعم أحرف حتمي بدلاً من ذلك.

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

الملجأ لا يشبك أبداً، لذا حتى الصفوف الباردة تبقى سريعة.

## 8. ملجأ صورة Open Graph

استخدم جلب من جانب الخادم لدمج شعار في بطاقة OG المُنشأة ديناميكياً الخاصة بك.

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

استخدم مفتاح **خادم** هنا وليس مفتاح متصفح — وظائف الحافة هي من جانب الخادم، ومفتاح الخادم هو ما ينجو من رؤوس الأصول غير المقيدة.

## 9. التوقيع من جانب الخادم للواجهات الحساسة

عندما لا تريد أن يكون عنوان URL عاماً (على سبيل المثال أدوات الإدارة الداخلية)، وكيل عبر الخلفية.

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

لا مفتاح API في مصدر الصفحة، وأنت تتحكم في التخزين المؤقت عند CDN الخاص بك.

## 10. مساعد TypeScript

يحافظ مساعد واحد على بناء عنوان URL متسقاً عبر قاعدة الأكواس.

```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` يحمي من الأحرف غير المعتادة في النطاقات ويجعل المساعد آمناً للدعوة مع مدخل غير موثوق.

## 11. Preconnect لتدفئة الاتصال مبكراً

للوحات المعلومات التي تعرض عشرات الشعارات فوق الطي، الطلب الأول يدفع مقابل DNS و TCP و TLS. أضف `<link rel="preconnect">` واحد إلى رأس المستند حتى يكون الاتصال جاهزاً قبل أول `<img>` — كل شعار لاحق يحصل على بداية سريعة دون انفجار preload لكل عنوان URL.

```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` يحل DNS ويفتح مصافحة TCP/TLS على الفور؛ `dns-prefetch` هو ملجأ رخيص للمتصفحات التي تتجاهل preconnect. تلميحات اثنتان فقط، بغض النظر عن عدد الشعارات التي تعرضها الصفحة. تفضل هذا على `<link rel="preload" as="image">` لكل شعار — التحميلات المسبقة ثقيلة الوزن وتعد تجاه ميزانيات النطاق الترددي.

## الأسئلة الشائعة

### أي وصفة يجب أن أبدأ بها؟

للشعار الواحد، وصفة `<img>` العادية كافية. للقوائم والجداول، انتقل إلى فتحة Tailwind avatar ونمط التحميل الكسول.

### هل أحتاج إلى مفتاح للاختبار؟

لا. نقطة النهاية تعمل بدون تسجيل دخول لاستعراض منخفض الحجم. أضف مفتاح متصفح قبل الشحن إلى الإنتاج حتى يتم نسب الطلب بشكل صحيح والعد مقابل خطتك.

### ما الحجم الذي يجب أن أطلبه؟

طابق حجم الرسم في CSS، ثم اطلب `2x` ذلك لحدة الشاشات عالية الدقة. لا تطلب `1024` لفتحة بحجم 32 بكسل — فهذا يكلف النطاق الترددي ولا يبدو أفضل.

### كيف أتعامل مع الوضع المظلم بدون JavaScript؟

استخدم عنصر `<picture>` مع `<source>` مغلق بـ `media="(prefers-color-scheme: dark)"`. المتصفح يختار عنوان URL الصحيح في وقت الطلاء — لا خطاف React ولا إعادة عرض لكل شعار ولا نفقات لكل صف حتى في القوائم الطويلة.

### كيف أجعل قائمة الشعارات تحميل أسرع؟

أضف `<link rel="preconnect" href="https://api.clearlogo.dev">` واحد في رأس المستند. هذا يفتح DNS/TCP/TLS مرة واحدة لكل شعار على الصفحة، وهو أرخص من `<link rel="preload">` لكل عنوان URL.

### كيف أظهر ملجأ عندما لا تعيد واجهة برمجة التطبيقات أي شعار؟

استمع إلى `onError` على `<img>` واستبدل في دعم حرف أو رمز عام. وصفة ملجأ الخطأ أعلاه هي شكل الإنتاج.

### هل يمكنني استخدام مفتاح متصفح من عرض من جانب الخادم؟

يمكنك — لكن مفتاح الخادم ملاءمة أفضل لأنه يرسل الطلب عبر `Authorization: Bearer …` بدلاً من الاعتماد على فحوصات الأصل. لمكونات Next.js Server أو مسارات OG أو وكلاء الخلفية، استخدم مفتاح الخادم.

### كيف أخزن شعارات في CDN الخاص بي؟

استخدم وصفة التوقيع من جانب الخادم أعلاه. الرد من المنبع يتضمن `Cache-Control` طويل المدى، لذا يمكنك تعيين نفس الرؤوس على الوكيل الخاص بك وترك CDN يفعل بقية العمل.
