SuperAPI AI Directory

add-favicon

Frontend & websites

View repository

Updated 10-16 08:05

About this skill

Add Favicon

Goal

Complete a clear, readable, maintainable local favicon.svgfor the site, and configure the <link rel="icon"> that the browser will actually read.

This skill prioritizes documentation sites and batch sites in a monorepo. It uses Iconify as a source of design inspiration, but the final asset should be a standalone SVG file in the repository, avoiding runtime dependencies, broken external links, and blurry, cluttered icons in browser tabs.

Default design direction

Unless the user explicitly requests otherwise, design according to the following direction:

  • Iconify-first: First look for semantic and compositional inspiration from the Iconify icon library, preferring references such as lucide:* simple linear icons like these.
  • Lucide style: Transparent background, linear strokes, rounded caps, rounded joins, few paths, ample whitespace.
  • No background block: By default, do not use a black circular base, dark square, gradient base, shadow base, or decorative disc. The user has already expressed that “displaying the icon directly looks better.”
  • At most 2 colors: Usually 1 primary color is enough; the second color is only for emphasis, and do not make rainbows, gradients, or multicolor illustrations.
  • Readable at small sizes: Work backward on complexity using the browser’s 16 px favicon as the standard. Details that cannot be seen clearly should be deleted or merged.
  • No text preferred: Avoid letters, abbreviations, and long text. Text in a favicon usually turns into a blur.

Workflow

1. Discover sites and configuration

First confirm whether the user wants to handle a single site or batch sites. For a monorepo, prefer discovering via the repository structure:

rg --files | rg '(^|/)\.vitepress/config\.(ts|mts|js|mjs)$'
rg --files | rg '(^|/)package\.json$'

Read each site’s:

  • VitePress/VuePress configuration file
  • Site title, package name, README, or homepage
  • Existing public/favicon.svg
  • Existing head configuration
  • User-specified site list and exclusions

If the user explicitly provides a site list, use the user’s list as the source of truth; if additional sites are found, list them as candidates first, and do not expand the scope without authorization.

2. Confirm the favicon placement path

Do not place the file at .vitepress/public/favicon.svgbased on experience. The default public asset directory for VitePress is usually under the site source directory public:

<vitepress-source-root>/public/favicon.svg

For example:

packages/utils/src/public/favicon.svg
packages/claude-notifier/src/docs/public/favicon.svg
packages/vitepress-preset-config/src/docs/public/favicon.svg

Only when the project already has configuration or documentation that clearly changes the public directory to .vitepress/public , use .vitepress/public/favicon.svg。

How to determine:

  • Look at the root in the VitePress command, for example vitepress build src means the source directory is src, and the public directory is usually src/public。
  • Check whether the existing build output will copy public/favicon.svg to .vitepress/dist/favicon.svg。
  • Check whether the config has a custom srcDir、outDir or public-related configuration.

Pure Nitro v3 API project

A pure Nitro API has no HTML head to inject into. Place favicon.svg in the project root’s public/favicon.svg, then add the browser default /favicon.ico fallback:

import { defineHandler, redirect } from "nitro/h3";

export default defineHandler(() => redirect("/favicon.svg", 302));

The file should be server/routes/favicon.ico.get.ts; Nitro v3 uses redirect, and do not continue to use the deprecated sendRedirect. For this route in tests/favicon-route.test.ts , add describe/test, asserting 302 and Location: /favicon.svg, and check after building .output/public/favicon.svg。

3. Configure head

Explicitly add the favicon in the site config:

head: [["link", { rel: "icon", type: "image/svg+xml", href: "/favicon.svg" }]],

Follow the project's existing config style:

  • If there is already head, only append the missing favicon entries to avoid duplication.
  • If the config is generated via setUserConfig()、defineConfig() or a custom wrapper, reuse the existing wrapper and do not change the architecture.
  • If a png/ico favicon already exists, prefer keeping it and adding an SVG unless the user requests migration; do not delete old assets without reason.

4. Choose icon semantics

Choose a different icon for each site, but keep a consistent style. Selection logic:

Site semantics Iconify/Lucide inspiration
Toolkit, general tools lucide:wrench, lucide:settings, lucide:blocks
Deployment, Vercel, release lucide:cloud-upload, lucide:rocket, lucide:upload-cloud
Notifications, reminders lucide:bell, lucide:message-circle
Domain, network, site lucide:globe, lucide:network
Config, presets, templates lucide:sliders-horizontal, lucide:badge-check, lucide:settings
Testing, experiments, samples lucide:flask-conical, lucide:test-tube
Docs, knowledge base lucide:book-open, lucide:file-text

Avoid duplicate icons within the same batch of sites, unless two sites truly have the same semantics.

5. Write the SVG

The final SVG should be a local file, with the recommended structure:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none">
  <path
    d="..."
    stroke="#2563eb"
    stroke-linecap="round"
    stroke-linejoin="round"
    stroke-width="2.6"
  />
</svg>

Design constraints:

  • viewBox Use 0 0 32 32to make it easier to bolden and add whitespace for the favicon.
  • stroke-width Usually between 2.4 and 3 ; it must still be clear at 16 px.
  • Remove small details that are too thin, too dense, or have too many intersections.
  • Do not use filter, complex masks, gradients, large background areas, or embedded images.
  • Do not use external links,<script>, event attributes, or unnecessary metadata.
  • If borrowing paths from Iconify/Lucide, you must re-simplify, bolden, and adjust whitespace for the favicon size, rather than copying the complex icon as-is.

6. Batch implementation strategy

When processing in batches, first produce a mapping table, then modify the files:

站点 | public 路径 | config 路径 | 图标语义 | 主色

Implementation order:

  1. Find all target sites.
  2. Define a semantic icon and color for each site.
  3. Write the local public/favicon.svg。
  4. Add head。
  5. Build or do a minimal validation.
  6. Spot-check the build output and the online paths.

7. Verification

At minimum, do these checks:

rg -n "favicon.svg|rel: \"icon\"|rel=\"icon\"" <目标配置和构建产物>

For VitePress, prioritize verifying:

  • public/favicon.svg exists.
  • After building, .vitepress/dist/favicon.svg exists.
  • After building, index.html contains <link rel="icon" type="image/svg+xml" href="/favicon.svg">。

For a pure Nitro v3 API, additionally verify that GET /favicon.ico returns 302 and Location points to /favicon.svg,GET /favicon.svg returns 200 and image/svg+xml。

If the site is already deployed, additionally verify:

curl -I https://example.com/favicon.svg
curl -s https://example.com/ | rg 'favicon|rel="icon"|image/svg\+xml'

If the user requests a visual display, use an available browser MCP or generate a local preview page to show the candidates. When displaying, focus on the three sizes 16 px, 24 px, and 32 px, not just the enlarged image.

Content to output to the user

When finished, explain with a brief checklist:

  • Which sites were processed.
  • The icon semantics used for each site.
  • The favicon file paths and config paths.
  • Which verifications were run.
  • If it does not take effect online, it means the issue is that the deployment was not updated, caching, or a domain alias problem. Do not conflate "configured locally" with "effective online."

Common mistakes

  • Putting favicon.svg into .vitepress/public, but the project's actual source directory is src or docs, causing the build output to have no favicon.
  • Wrapping every icon in a black circular background or dark square makes it look heavy in browser tabs.
  • Directly copying a complex Iconify SVG makes it look like a tangle of lines at 16 px.
  • Only writing the SVG file without configuring head, relying on the browser to guess the path.
  • A pure Nitro project only adds public/favicon.svg, without providing a /favicon.ico fallback, so the browser still shows the default icon.
  • Continuing to use the deprecated sendRedirectin Nitro v3; it should be changed to return redirect(location, status)。
  • Batch sites use the same icon, losing project semantics.
  • Not verifying after deployment /favicon.svg, causing it to be correct locally but still 404 online.