Overview
This guide uses the Next.js-specific RealFaviconGenerator wizard and the Next.js file conventions for icons. Generate once with the wizard, then drop the produced files into the app/
and public/
folders as described below.
Prerequisites
- Next.js App Router (app/ directory).
- A vector or high-resolution logo (SVG preferred, PNG supported).
- Project has
app/layout.tsx
and apublic/
directory.
Generate icons
Open the wizard and upload a logo. Keep defaults for Classic/SVG favicon, Apple Touch icon, and Web App Manifest, or set brand names and colors as needed.
At the bottom, keep Favicon path as /
, then generate and download two packages: App files and Public files - no manual <link>
markup is required.
Place the files
Unzip App files directly into the root of app/
alongside layout.tsx
- do not nest in subfolders.
# Root of the app/ directory (App Router)
app/
├─ layout.tsx
├─ page.tsx
├─ favicon.ico
├─ apple-icon.png
├─ icon.svg
├─ icon.png
└─ manifest.json
Unzip Public files into public/
- these 192x192 and 512x512 PNGs are referenced by the generated manifest.json
.
public/
├─ web-app-manifest-192x192.png
└─ web-app-manifest-512x512.png
How Next.js wires it
Next.js auto-detects app/favicon.ico
and builds the <link>
tags. Extra icons are picked up via app/**/*/icon.(ico|png|jpg|jpeg|svg)
and app/**/*/apple-icon.(png|jpg|jpeg)
, including numbered variants like icon1.png
.
The wizard's manifest.json
in app/
points to /web-app-manifest-192x192.png
and /web-app-manifest-512x512.png
in public/
. Keep paths and names in sync if renaming.
Manifest example
Use the generated manifest as-is and adjust name
, short_name
, theme_color
, and background_color
to match the brand.
{
"name": "MyWebSite",
"short_name": "MySite",
"icons": [
{ "src": "/web-app-manifest-192x192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/web-app-manifest-512x512.png", "sizes": "512x512", "type": "image/png" }
],
"theme_color": "#111111",
"background_color": "#ffffff",
"display": "standalone",
"start_url": "/"
}
Optional overrides
Conventions are usually enough, but metadata.icons
in app/layout.tsx
can add formats or sizes and set a custom manifest
path if required.
// app/layout.tsx
export const metadata = {
icons: {
icon: [
{ url: '/favicon.ico' },
{ url: '/icon.svg', rel: 'icon', type: 'image/svg+xml', sizes: 'any' },
{ url: '/icon.png', type: 'image/png', sizes: '32x32' }
],
apple: [{ url: '/apple-icon.png' }]
},
manifest: '/manifest.json'
};
Verify locally
Start the dev server and run the realfavicon
check against the local port to open a validation report.
npm run dev
npx realfavicon check 3000
Wizard choices
- Prefer SVG as the regular icon, add PNG as fallback if needed.
- Apple Touch: Use the icon as is is fine unless a background is required.
- Manifest: keep default 192/512 icons, set brand names and colors.
- Keep Favicon path as
/
for stable URLs.
Troubleshooting
- If icons don't refresh, hard-reload or clear site data - favicons are heavily cached.
- If Android/PWA icons 404, verify
manifest.json
paths match files inpublic/
. - If a dark tab shows poor contrast, provide both SVG and a small PNG variant.
- If iOS shows a black background, use a non-transparent icon or add a background in the wizard.
Maintenance tips
- Keep
favicon.ico
only atapp/
root, useicon.*
/apple-icon.*
elsewhere. - Prefer one authoritative SVG plus a 32x32 PNG, let the manifest handle 192/512 sizes.
- Re-run the wizard on re-brands and replace both
app/
andpublic/
packages together.