实用片段用于徽标最终出现的常见形状:一个
<img>标签、一个React组件、一个Next.js Image、一个Tailwind头像插槽、一个深色模式感知<picture>元素、一个OG图像后备和一个服务器签名URL。每个片段都针对公开https://api.clearlogo.dev端点工作。所有示例都假设你有一个浏览器密钥(用于客户端代码)或一个服务器密钥(用于后端代码)。从仪表板创建密钥。
1. 普通HTML
最快的集成——将URL粘贴到<img>标签中。
<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组件
一个小的可重用组件涵盖大多数产品UI需求。
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"使长列表(CRM、目录、帐户表)不会阻止绘制。
3. Next.js <Image>
将API主机添加到next.config.js一次,然后在任何地方使用优化的<Image>组件。
// 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
/>
);
}
请求size * 2用于HiDPI显示器上的Retina清晰度。如果你想要API中的WebP协商流向客户端,使用unoptimized;如果你想要Next.js自己处理格式协商,删除它。
4. Tailwind头像插槽
将徽标放入一个固定的UI插槽中,在品牌之间保持视觉一致。
<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或每个徽标的重新渲染。
<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组件:
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>
);
}
API在不存在深色版本时回退到浅色变体,所以请求theme=dark总是安全的。对于应用级主题开关(不是OS级),从你的主题状态而不是prefers-color-scheme驱动来源URL。
6. 列表渲染与占位符
对于长列表,立即渲染占位符,使空插槽不会闪烁。
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. 错误后备与第一个字母
如果API找不到域的徽标,渲染一个确定性字母头像代替。
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卡中。
// 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 },
);
}
在这里使用服务器密钥,而不是浏览器密钥——Edge函数是服务器端的,服务器密钥在不受限制的源标头中存活。
9. 后端签名用于敏感UI
当你不想要URL公开时(例如内部管理工具),通过你的后端代理。
// 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/logo/{domain}——页面源中没有API密钥,你在自己的CDN处控制缓存。
10. TypeScript助手
一个单个助手在代码库中保持URL构造一致。
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. 预连接以提前准备连接
对于渲染几十个徽标在折叠上方的仪表板,第一个请求支付DNS、TCP和TLS。将单个<link rel="preconnect">添加到你的文档标题,以便在第一个<img>命中前连接准备就绪——每个后续徽标都获得一个抢先而没有每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立即解决DNS并打开TCP/TLS握手;dns-prefetch是忽略预连接的浏览器的廉价后备。总共两个提示,无论页面渲染多少徽标。相比每个徽标的<link rel="preload" as="image">更倾向于这个——预加载很重,计入带宽预算,如果渲染的URL最终与预加载的略有不同(大小、主题、令牌)也无助益。
常见问题
我应该从哪个食谱开始?
对于单个徽标,普通<img>食谱就足够了。对于列表和表,跳到Tailwind头像插槽和延迟加载模式。
我需要一个密钥用于测试吗?
否。端点对低体积浏览匿名工作。在你发布到生产前添加浏览器密钥,以便请求被正确归因并计入你的计划。
我应该请求什么大小?
匹配CSS中的渲染大小,然后请求2x用于Retina清晰度。不要为32像素插槽请求1024——它浪费带宽并看起来不会更好。
我如何在没有JavaScript的情况下处理深色模式?
使用由media="(prefers-color-scheme: dark)"门控的<picture>元素与<source>。浏览器在绘制时选择正确的URL——没有React钩子、没有每个徽标的重新渲染、长列表中没有每行开销。
我如何使徽标列表加载更快?
在你的文档标题中添加单个<link rel="preconnect" href="https://api.clearlogo.dev">。这为页面上的每个徽标打开一次DNS/TCP/TLS,这比每URL的<link rel="preload">便宜。
当API返回没有徽标时,我如何显示后备?
在<img>上监听onError并交换字母头像或通用图标。上面的错误后备食谱是生产形状。
我可以从服务器端渲染使用浏览器密钥吗?
你可以——但服务器密钥是更好的拟合,因为它通过Authorization: Bearer …而不是依靠源检查发送请求。对于Next.js服务器组件、OG路由或后端代理,使用服务器密钥。
我如何在我自己的CDN处缓存徽标?
使用上面的后端签名食谱。上游响应包括长期Cache-Control,所以你可以在你的代理上设置相同的标题并让你的CDN做其余部分。
在操场中尝试真实域
一旦食谱形状看起来正确,交换你自己的几个客户或合作伙伴域并在你发布之前预览结果。