Der Next.js App Router setzt Favicons über Datei-Konventionen im app/-Verzeichnis und die Metadata API um. Lege favicon.ico, icon.png oder apple-icon.png in app/ ab, oder definiere Icons in layout.tsx via export const metadata. Next.js erzeugt die passenden link-Tags beim Build.
Dieser Leitfaden deckt alle unterstützten Wege, typische App-Router-Fallen und die Prüfung auf deployed Vercel- oder Self-Hosted-URLs vor Launch ab.
Kurzantwort: drei Wege zu Favicons
| Methode | Geeignet für |
|---|---|
Datei-Konvention (app/icon.png) | Einfache statische Icons, null Config |
app/favicon.ico | Legacy-Browser-Fallback unter /favicon.ico |
metadata.icons in layout.tsx | Mehrere Größen, SVG, Manifest-Links |
Datei-Konventionen und explizite Metadata lassen sich kombinieren. Dasselbe Icon nicht doppelt im HTML-Head ausgeben.
Methode 1: Datei-Konventionen (empfohlener Einstieg)
Next.js 13+ erkennt spezielle Dateien in app/:
app/
favicon.ico
icon.png # oder icon.jpg, icon.svg
apple-icon.png # Apple Touch Icon
icon.png- Next.js erzeugt passendelink rel="icon"-Tagsapple-icon.png- wird zuapple-touch-iconfavicon.ico- wird unter/favicon.icoausgeliefert
Next.js optimiert und emittiert Tags automatisch bei next build. Kein manuelles HTML nötig.
Unterstützte Dateinamen
Laut Next.js-Docs funktionieren:
favicon.ico- nur.icoicon-.ico,.jpg,.jpeg,.png,.svgapple-icon-.jpg,.jpeg,.png
Nummerierte Varianten wie icon1.png sind möglich; für komplexe Setups ist explizite Metadata klarer.
Methode 2: Metadata API
Volle Kontrolle über das Root-Layout:
// app/layout.tsximport type { Metadata } from 'next'export const metadata: Metadata = { icons: { icon: [ { url: '/favicon-32x32.png', sizes: '32x32', type: 'image/png' }, { url: '/favicon-16x16.png', sizes: '16x16', type: 'image/png' }, ], apple: [ { url: '/apple-touch-icon.png', sizes: '180x180', type: 'image/png' }, ], other: [ { rel: 'mask-icon', url: '/safari-pinned-tab.svg', color: '#5bbad5', }, ], },}Statische Dateien in public/:
public/
favicon-32x32.png
favicon-16x16.png
apple-touch-icon.png
site.webmanifest
Manifest separat verlinken:
export const metadata: Metadata = { manifest: '/site.webmanifest', icons: { /* ... */ },}Entspricht handgeschriebenem HTML. Tag-Referenz: Favicon per HTML einbinden.
Methode 3: Dynamische Icons per Code
Next.js kann Icons programmatisch erzeugen:
app/
icon.tsx # oder icon.js
apple-icon.tsx
Beispiel app/icon.tsx:
import { ImageResponse } from 'next/og'export const size = { width: 32, height: 32 }export const contentType = 'image/png'export default function Icon() { return new ImageResponse( ( <div style={{ fontSize: 24, background: '#000', width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', }} > A </div> ), { ...size } )}Sinnvoll, wenn Favicons zur Marke oder Umgebung passen müssen. Für Marketing-Sites sind statische PNGs einfacher zu testen.
PWA-Manifest-Icons in Next.js
Tab-Favicons und PWA-Install-Icons sind getrennt. Manifest in public/site.webmanifest:
{ "name": "Meine App", "icons": [ { "src": "/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" }, { "src": "/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" } ]}In Metadata referenzieren:
export const metadata: Metadata = { manifest: '/site.webmanifest',}Größen-Details: Favicon-Größen-Leitfaden.
Pages Router vs. App Router
Noch auf Pages Router? Nutze pages/_document.tsx oder public/favicon.ico. App-Router-Konventionen gelten nicht für pages/.
Bei Migration:
- Icons von
public/oder_document.tsx-Links nachapp/-Konventionen verschieben - Doppelte
Head-Tags entfernen, die Metadata widersprechen - Production nach Migration neu testen
Typische Next.js-Favicon-Fehler
Icons nur in public/ ohne Metadata
public/favicon.ico liegt unter /favicon.ico, aber Next.js emittiert ohne Konventionen oder Metadata keine PNG-link-Tags. Browser fallen auf ICO zurück und verpassen 16×16/32×32-Deklarationen.
Doppelte Tags aus Layout und Page-Metadata
Child-Layouts mergen Metadata. Definieren Root und Nested Layout beide icons, entstehen Duplikate. Icon-Config nur im Root-app/layout.tsx.
Falsche Bildabmessungen
apple-icon.png als 180×180 exportieren. Tab-Icons als 32×32 und 16×16. Hochskaliertes kleines Logo wird unscharf. Siehe Favicon unscharf.
Build-Output auf CI vergessen
Icons in app/ werden beim Build verarbeitet. Überspringt CI next build oder cached veraltetes .next, gehen alte Icons live. Nach Rebrand Dateinamen ändern.
SVG ohne PNG-Fallback
Safari und manche Kontexte ignorieren SVG-Favicons. PNG-Fallback neben icon.svg ausliefern.
Next.js-Favicons vor Deploy testen
Localhost zeigt Icons, Production-Pfade hinter CDN und Asset-Prefix unterscheiden sich.
Schritt 1: Build-Output prüfen
Lokal next build ausführen. Seitenquelltext auf next start prüfen: Tags im HTML ohne Client-JS.
Schritt 2: Staging oder Production scannen
Preview deployen. Favicon Check mit Preview-URL: alle Icons 200, /favicon.ico vorhanden, Manifest-Icons erreichbar.
Schritt 3: basePath und assetPrefix
Setzt next.config.js basePath oder assetPrefix, müssen Icon-URLs den Prefix enthalten. Scan findet 404s sofort.
Schritt 4: Open Graph mitprüfen
Next.js metadata.openGraph ist unabhängig von Favicons. Vor Launch Open Graph Check auf derselben URL. Ein Deploy in layout.tsx betrifft oft beides.
Vollständiges Beispiel: production-ready
app/
layout.tsx
favicon.ico
icon.png
apple-icon.png
public/
favicon-16x16.png
favicon-32x32.png
android-chrome-192x192.png
android-chrome-512x512.png
site.webmanifest
// app/layout.tsximport type { Metadata } from 'next'export const metadata: Metadata = { title: 'Meine Site', manifest: '/site.webmanifest', icons: { icon: [ { url: '/favicon-32x32.png', sizes: '32x32', type: 'image/png' }, { url: '/favicon-16x16.png', sizes: '16x16', type: 'image/png' }, ], },}export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="de"> <body>{children}</body> </html> )}Datei-Konventionen für favicon.ico, icon.png, apple-icon.png. Metadata für explizite Größen und Manifest.
Nach Deploy: Favicon Check und Favicons testen vor Launch.
Deployment auf Vercel, Netlify und Docker
Das Hosting ändert selten das Favicon-Markup, aber Cache und Pfade.
Vercel: App-Router-Konventionen funktionieren out of the box. Preview-Deployments haben eigene URLs. Jede Preview vor Merge scannen. Nach Merge auf Production erneut scannen, weil Edge-Cache alte Static Files minutenlang halten kann.
Netlify / Static Export: Bei output: 'export' prüfen, ob Icons im exportierten out/-Ordner landen. Dynamische icon.tsx-Routen verhalten sich anders als bei Server-Builds. Statische PNGs in app/ oder public/ bevorzugen.
Docker / Self-Hosted: Reverse Proxy darf link-Tags nicht aus HTML strippen. Manche Security-Middleware entfernt unbekannte Head-Elemente. Container-Antwort mit lokalem next start vergleichen.
Monorepo: Liegt die Next-App unter /apps/web, gehören Favicon-Dateien in das app/-Verzeichnis dieser App, nicht ins Monorepo-Root.
Migration von Pages Router
Beim Upgrade bleiben oft doppelte Icon-Pfade.
Migrations-Checkliste:
pages/_document.tsxauf manuelle Favicon-link-Tags prüfenpublic/favicon.icoprüfen, ob Umzug nachapp/favicon.icosinnvoll ist<Head>-Favicon-Einträge von Einzelseiten entfernen- Production-Scan nach erstem App-Router-Deploy
- CDN-Purge-Regeln aktualisieren, wenn Icon-URLs wechseln
Während der Migration können beide Router auf verschiedenen Routen unterschiedliches Head-Output liefern. Marketing-Pages und Dashboard-Routen separat testen, wenn Layouts abweichen.
metadata.icons vs. Datei-Konvention - Entscheidungshilfe
| Kriterium | Datei-Konvention | metadata.icons |
|---|---|---|
| Setup-Aufwand | minimal | mittel |
| Mehrere PNG-Größen | begrenzt | vollständig |
| SVG + PNG-Fallback | möglich | explizit steuerbar |
| Team-Verständlichkeit | hoch | mittel |
Für Marketing-Sites reicht oft app/icon.png plus app/favicon.ico. SaaS mit PWA sollte metadata.icons plus Manifest nutzen.
Internationalisierung (i18n) in Next.js
Mit next-intl oder ähnlichen Locale-Prefixes gelten Favicon-Datei-Konventionen in app/ weiter global. Metadata-Icons brauchen keine Duplikation pro Locale, außer Marken unterscheiden sich je Markt.
Scans auf:
/en-Startseite/de-Startseite
Liefert nur eine Locale kaputtes Head-Output, locale-spezifische Layouts auf versehentliche Metadata-Overrides prüfen.
Edge Runtime und Middleware
Middleware-Rewrites dürfen statische Icon-Pfade nicht abfangen. Ist der Middleware-Matcher zu breit, können /favicon.ico-Requests Auth-Middleware treffen und 401 liefern.
Icon-Pfade in Middleware-Config ausschließen:
export const config = { matcher: ['/((?!favicon.ico|icon.png|apple-icon.png).*)'],}Nach Middleware-Änderungen Favicon Check auf Production erneut ausführen.
Performance: Icons schlank halten
Next.js optimiert app/icon.png beim Build. Trotzdem:
- Keine 2-MB-PNGs als Tab-Icon-Quelle
- ICO-Dateien unter 100 KB halten
- SVG-Favicons schlank halten, komplexe Pfade vermeiden
Favicons werden bei fast jedem Page Load mitbezogen. Kleine Dateien helfen besonders auf langsamen Mobilnetzen.
Zusammenfassung für Code-Reviews
Beim Review von Pull Requests mit Dateien unter app/icon* oder metadata.icons kurz prüfen:
- Keine doppelten Tags in Child-Layouts
- PWA-Manifest verlinkt, wenn Manifest-Icons existieren
- Preview-URL im PR-Kommentar mit Scan-Ergebnis
Das hält Favicon-Regressions sichtbar, ohne eigenes QA-Dokument pro Feature.
Vor dem Merge reicht oft ein Link zur Preview-URL im PR plus bestätigter Favicon Check-Scan. So bleibt die Historie nachvollziehbar, wenn Wochen später jemand nach dem Tab-Icon fragt.
Wer App Router und Pages Router parallel betreibt, sollte beide Entry Points in der QA-Liste führen, bis die Migration abgeschlossen ist.
FAQ
Wo lege ich favicon.ico im Next.js App Router ab?
Direkt in app/. Next.js liefert unter /favicon.ico nach Build. Alternativ public/favicon.ico, aber app/-Konvention integriert sich in die Metadata-Pipeline.
Erzeugt Next.js Favicon-link-Tags automatisch?
Ja, mit Datei-Konventionen (app/icon.png, app/favicon.ico) oder metadata.icons. Tags stehen im servergerenderten HTML-Head.
SVG-Favicons in Next.js?
Ja. app/icon.svg oder SVG in metadata.icons. Immer PNG-Fallback für Safari und ältere Clients.
Warum funktioniert das Favicon in dev, aber nicht in Production?
assetPrefix, CDN-Cache und unterschiedliche Preview-/Production-Domains prüfen. Deployed URL mit Favicon Check scannen.
Mehrere Favicon-Größen in Next.js?
metadata.icons.icon als Array mit { url, sizes, type } auf Dateien in public/, oder nummerierte icon1.png, icon2.png in app/.
App Router vs. Metadata in next/head?
Kein next/head im App Router. Metadata API oder Datei-Konventionen. next/head ist für Pages Router.
Cached Vercel Favicons?
Vercel respektiert Standard-Cache-Header. Nach Icon-Änderung redeployen und Inkognito testen. Dateien umbenennen bei stale Icons.
Müssen Next.js-Favicons zu Open-Graph-Bildern passen?
Nein. Favicons sind kleine quadratische Tab-Icons. OG-Bilder große Landscape-Share-Previews. Siehe Favicon vs. Open-Graph-Bild.
Fazit
Next.js App Router Favicons kommen aus app/favicon.ico, app/icon.png, app/apple-icon.png oder metadata.icons im Root-Layout. Datei-Konventionen mit expliziten PNG-Größen und Web-Manifest für PWA kombinieren.
Lokal bauen, Preview deployen, mit Favicon Check scannen. Bei Social-Metadata im selben Release Open Graph Check dazu.