@cypress-design/favicon

中文文档
1.0.0发布于 2026/09/25MITTypeScriptESM + CJS零依赖近 30 天下载 5086

The Cypress favicon assets and the head markup that declares them.

原始使用文档
文档目录11 节
  1. Why this is a file copy, not an import
  2. Usage
  3. Astro
  4. Docusaurus
  5. EJS and other server-rendered HTML
  6. Why not a component everywhere
  7. Two things deliberately absent
  8. The ICO rule
  9. What's in the box
  10. Local development
  11. Why there is no mask-icon

@cypress-design/favicon

The Cypress favicon assets and the head markup that declares them.

Most sites should not install this directly. If your <head> is rendered by Astro, install @cypress-design/vue-favicon or @cypress-design/react-favicon instead — each brings this package, its icon files and its copy command with it. Install this package on its own only when your head cannot render a component: a Docusaurus plugin, an EJS template, or other server-rendered HTML. Full documentation: Favicon.

Why this is a file copy, not an import

A favicon never enters the document. The browser fetches it as a standalone URL and paints it into its own chrome — the tab strip, bookmarks, history — usually before the JavaScript bundle exists. So unlike the rest of the design system, this package has to put real files on disk.

Usage

Copy the assets into whatever directory your site serves statically, as a prebuild step:

// package.json
{
  "scripts": {
    "prebuild": "cypress-favicon public", // `static` for Docusaurus
  },
}

Then declare the markup. Which form you use depends on what your head layer accepts — all three come from the same FAVICON_LINKS array, so they cannot disagree with each other.

Astro

---
// use the build matching a framework your Astro config registers
import Favicon from '@cypress-design/vue-favicon'
// or, on a site whose Astro config registers React:
// import Favicon from '@cypress-design/react-favicon'
---
<head>
  <Favicon />
</head>

Picking the wrong one is not merely redundant. Astro finds a renderer by asking each registered one in turn, and @astrojs/react's check throws on a compiled Vue component rather than returning false — so a Vue component on a site that registers React first crashes every page.

Pass links to narrow the list, e.g. for a site that ships no web manifest:

<Favicon links={FAVICON_LINKS.filter((l) => l.rel !== 'manifest')} />

Docusaurus

A Docusaurus plugin injects objects rather than markup, so there is no component to render:

const { faviconHeadTags } = require('@cypress-design/favicon')

module.exports = async function favIcon() {
  return {
    name: 'docusaurus-plugin-favicon',
    injectHtmlTags: () => ({ headTags: faviconHeadTags() }),
  }
}

EJS and other server-rendered HTML

<head>
  <%- faviconLinksHtml() %>
</head>

EJS templates take a string. This is also the only form that works on a page with no JavaScript at all — a server-rendered page with no <script> tags has nothing for a component to mount into.

Why not a component everywhere

The component renders <link> elements, so it needs a framework doing the rendering at the point the <head> is built. Astro does. A Docusaurus plugin hands back descriptors before any component tree exists, and an EJS template has no component runtime. A client-side React component can reach the head after hydration, but a favicon is fetched during the initial HTML parse — so injecting it later means the browser has already asked for /favicon.ico and moved on.

Two things deliberately absent

No rel="icon" entry for favicon.ico, and no rel="mask-icon" at all.

The ICO rule

FAVICON_LINKS deliberately contains no rel="icon" entry for favicon.ico.

Measured against Chrome 153 and Safari 26.5: when an ICO is declared, it beats the SVG in both engines regardless of sizes or document order, and Chrome does not even download the SVG. The widely copied <link rel="icon" href="/favicon.ico" sizes="any"> line is what prevents the adaptive icon from being used, not what enables it.

The ICO is still shipped and still served. Clients that want it — Safari before 26, crawlers, unfurlers, RSS readers — request /favicon.ico from the origin root by convention, without reading your markup. Keep the file at the root and leave it undeclared.

What's in the box

FileUsed by
favicon.svgChrome, Edge, Firefox — adapts to light/dark via prefers-color-scheme
favicon.icoSafari before 26, crawlers, unfurlers. Real ICO container, 16/24/32/48/64
apple-touch-icon.pngiOS home screen. 180×180, no alpha
android-chrome-*.pngAndroid and installed PWAs, via the manifest

The ICO is baked from the dark variant with the navy disc filled. It cannot adapt, so it has to be one image that survives on a light or a dark tab strip — a filled disc gives the wordmark its own background either way.

Safari 26 renders the SVG but always resolves it light, so its dark-mode tab shows the light variant. That is legible, just not identical to Chrome.

Local development

exports points at dist/, so a linked consumer sees built output, not source. Rebuild after editing:

yarn workspace @cypress-design/favicon build

Why there is no mask-icon

Safari required a flat monochrome safari-pinned-tab.svg for pinned tabs from Safari 9 (2015). Safari 12 (2018) started using the regular favicon there instead, and it has never been required since. Verified inert in Safari 26.5: a pinned tab renders the full-colour favicon whether or not the tag is declared. Apple's guidance for it is archived, and apple.com no longer ships it.

Note that Safari renders favicon.svg but always resolves it light, in both appearances — so a Safari dark-mode tab shows the light variant while Chrome and Firefox show the dark one.

版本与发布记录

@cypress-design/favicon 共发布 1 个版本,首次发布于 2026/09/25;过去 12 个月发布了 1 个版本。

版本发布日期距今
1.0.0latest2026/09/251 个月前

关于 @cypress-design/favicon 的常见问题

@cypress-design/favicon 是什么?

The Cypress favicon assets and the head markup that declares them.

如何安装 @cypress-design/favicon?

在项目目录运行 npm install @cypress-design/favicon,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 cypress-favicon,可以用 npx cypress-favicon 直接运行。

@cypress-design/favicon 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cypress-design/favicon 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@cypress-design/favicon 可以商用吗?

@cypress-design/favicon 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cypress-design/favicon 的下载量有多少?

根据 npm 官方下载统计,@cypress-design/favicon 在 2026/10/11 – 2026/11/09 这 30 天内被下载 5,086 次,日均约 170 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cypress-design/favicon 还在维护吗?

最新版本 1.0.0 发布于 2026/09/25(1 个月前);至今共发布 1 个版本,其中过去 12 个月发布了 1 个;首次发布于 2026/09/25。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。