Skip to content

Icons

Eminence detects existing icon files in Astro’s configured publicDir. It never creates, resizes, copies, or modifies them, so the same files are served by astro dev and copied into production builds by Astro.

Discovery is enabled by default. icons: true enables it explicitly; icons: false disables discovery and its recommendation.

Public file Result
favicon.svg <link rel="icon" href="/favicon.svg" sizes="any" type="image/svg+xml">
favicon.png <link rel="icon" href="/favicon.png" sizes="32x32" type="image/png">
apple-touch-icon.png <link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180" type="image/png">
favicon.ico No tag; its presence satisfies the fallback favicon recommendation.

Only these exact root-level filenames are inspected. The PNG dimensions are declared from their documented contracts; image bytes are not decoded or validated.

Browsers discover /favicon.ico by convention, so adding a tag for it is unnecessary. Eminence recommends the file when absent but never emits an HTML tag for it.

public/
├── favicon.ico
├── favicon.svg
├── favicon.png
└── apple-touch-icon.png
eminence({ icons: true });

Detected tags are merged with headTags.icons by href. Overrides passed directly to <Icons /> are applied last.

Manifest icons are separate and must be listed explicitly in manifest.icons; favicon dimensions are not suitable substitutes for installable application icons.

import { existsSync } from "node:fs";
import { fileURLToPath } from "node:url";
export type IconTag = {
rel: string;
href: string;
sizes?: string;
type?: string;
media?: "light" | "dark" | (string & {});
};
export type DetectedPublicIcons = {
tags: IconTag[];
hasFaviconIco: boolean;
};
export const FAVICON_ICO_RECOMMENDATION =
'Recommendation: add "public/favicon.ico" as a fallback favicon. Browsers discover this conventional path automatically, so Eminence does not emit a link tag for it.';
const existsInPublicDir = (publicDir: URL, fileName: string): boolean =>
existsSync(fileURLToPath(new URL(fileName, publicDir)));
export const detectPublicIcons = (publicDir: URL): DetectedPublicIcons => {
const tags: IconTag[] = [];
if (existsInPublicDir(publicDir, "favicon.svg")) {
tags.push({
rel: "icon",
href: "/favicon.svg",
sizes: "any",
type: "image/svg+xml",
});
}
if (existsInPublicDir(publicDir, "favicon.png")) {
tags.push({
rel: "icon",
href: "/favicon.png",
sizes: "32x32",
type: "image/png",
});
}
if (existsInPublicDir(publicDir, "apple-touch-icon.png")) {
tags.push({
rel: "apple-touch-icon",
href: "/apple-touch-icon.png",
sizes: "180x180",
type: "image/png",
});
}
return {
tags,
hasFaviconIco: existsInPublicDir(publicDir, "favicon.ico"),
};
};