Favicon Setup in Next.js — App Router Configuration

Configure favicons in a Next.js project using the App Router. Covers the app directory structure, metadata API, static files, and the generateMetadata function.

Framework Setup

Detailed Explanation

Favicon Setup in Next.js

Next.js provides built-in support for favicons and metadata through its App Router metadata API. Here is the recommended approach for setting up favicons in a Next.js project.

File-Based Approach (Recommended)

Next.js automatically serves favicon files placed in the app directory:

app/
├── favicon.ico          → served at /favicon.ico
├── icon.png             → served as <link rel="icon">
├── icon.svg             → served as <link rel="icon" type="image/svg+xml">
├── apple-icon.png       → served as <link rel="apple-touch-icon">
└── manifest.webmanifest → served as <link rel="manifest">

Using the Metadata API

In your root layout or page:

// app/layout.tsx
import type { Metadata } from "next";

export const metadata: Metadata = {
  icons: {
    icon: [
      { url: "/favicon-16x16.png", sizes: "16x16", type: "image/png" },
      { url: "/favicon-32x32.png", sizes: "32x32", type: "image/png" },
      { url: "/favicon.svg", type: "image/svg+xml" },
    ],
    apple: [
      { url: "/apple-touch-icon.png", sizes: "180x180" },
    ],
    other: [
      { rel: "mask-icon", url: "/safari-pinned-tab.svg" },
    ],
  },
  manifest: "/site.webmanifest",
};

Static Files in public

Place all favicon files in the public directory:

public/
├── favicon.ico
├── favicon-16x16.png
├── favicon-32x32.png
├── favicon-48x48.png
├── favicon.svg
├── apple-touch-icon.png
├── android-chrome-192x192.png
├── android-chrome-512x512.png
├── safari-pinned-tab.svg
└── site.webmanifest

Dynamic Favicons with generateMetadata

For pages that need different favicons:

export async function generateMetadata({ params }): Promise<Metadata> {
  const brand = await getBrand(params.slug);
  return {
    icons: {
      icon: brand.faviconUrl,
      apple: brand.appleTouchIconUrl,
    },
  };
}

Common Issues

  • Favicon not updating: Clear browser cache or use ?v=2 query string
  • 404 on favicon.ico: Ensure the file exists in app/ or public/
  • Metadata not applied: Check that metadata is exported from a Server Component
  • SVG not working: Verify the type attribute is set correctly

Use Case

Next.js developers setting up a new project or migrating from Pages Router to App Router need to know the correct way to configure favicons. This is the definitive guide for Next.js favicon implementation, covering both simple static setups and advanced dynamic favicon scenarios.

Try It — Favicon Checker

Open full tool