How to Add an SVG Favicon in Next.js
Add an SVG favicon in Next.js with the App Router icon convention or the metadata API, prepare the logo artwork for tiny sizes, and verify the result.
Contents
- The short answer
- Which method fits your project
- Step by step: App Router with the file convention
- Step by step: App Router with the metadata API
- Step by step: Pages Router
- Preparing the logo artwork for a favicon
- Technical requirements
- Design recommendations for small sizes
- Optional: adapting to dark mode
- Cleaning the export
- Browser support and fallbacks
- Verifying the result
- A note on rights
The short answer
In a Next.js project that uses the App Router, place a file named icon.svg directly inside the app directory. Next.js detects it through its file-based metadata convention and adds the matching icon link tag to the page head automatically, so no manual markup is needed. Keep a favicon.ico in the same top-level app directory as a fallback for browsers that do not display SVG favicons. In a project that uses the Pages Router, put the SVG in the public directory and reference it with a link tag through the Head component.
A favicon is the small icon a browser shows in tabs, bookmarks and history. An SVG (Scalable Vector Graphics) favicon describes the icon as geometry, meaning paths, shapes and fills defined in a coordinate system, rather than as a fixed grid of pixels. That lets one file render sharply at any size, but it does not guarantee the logo will read well at the tiny sizes a browser tab uses. That second problem is a design task, covered below.
Which method fits your project
| Setup | Where the SVG goes | How it is wired up |
| App Router, file convention | app/icon.svg | Automatic; Next.js generates the link tag |
| App Router, metadata API | public/ (any file name) | Declared in the icons field of exported metadata |
| Pages Router | public/ (any file name) | Manual link tag inside the Head component |
The file convention is the simplest option when one icon serves the whole site. The metadata API is useful when you want a custom file name, several icon variants, or different icons for different route segments. Behavior can differ between Next.js versions, and no version-specific evidence was supplied for this guide, so confirm the details against the documentation for the version your project uses.
Step by step: App Router with the file convention
- 1. Prepare the SVG artwork as described in the artwork section below.
- 2. Name the file icon.svg and save it directly inside the app directory, not in a subfolder, unless you intend it to apply only to that route segment.
- 3. Optionally add favicon.ico in the top-level app directory as a fallback. Next.js only honors favicon.ico at that top level.
- 4. Remove any manually written icon link tags from your root layout so they do not conflict with the generated ones.
- 5. Restart the development server if the new file is not picked up, then load the page.
app/
├── favicon.ico (optional raster fallback)
├── icon.svg (vector favicon)
├── layout.tsx
└── page.tsx
For an SVG icon, Next.js typically emits a link tag with rel set to icon, a type of image/svg+xml and sizes set to any, because a vector file has no single fixed pixel size.
Step by step: App Router with the metadata API
Put the file in the public directory, then declare it in the root layout. Paths starting with a slash resolve from public.
// app/layout.tsx
import type { Metadata } from 'next'
export const metadata: Metadata = {
icons: {
icon: [
{ url: '/logo-mark.svg', type: 'image/svg+xml' },
{ url: '/favicon.ico', sizes: 'any' },
],
},
}
Use either this approach or the app/icon.svg convention for a given icon, not both, to avoid duplicate or conflicting tags.
Step by step: Pages Router
Save the SVG in public, then add the link tags in a component that renders on every page, usually the custom App or Document.
// pages/_app.tsx
import Head from 'next/head'
import type { AppProps } from 'next/app'
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Head>
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<link rel="icon" href="/favicon.ico" sizes="any" />
</Head>
<Component {...pageProps} />
</>
)
}
Preparing the logo artwork for a favicon
Exporting the full logo as an SVG is rarely enough. A browser tab displays the icon at a very small size, commonly around 16 by 16 pixels on standard displays, where fine detail disappears. The checks below separate what the file technically needs from what are design recommendations.
Technical requirements
- Square viewBox: the viewBox attribute defines the drawing's coordinate system. A square viewBox, for example 0 0 32 32, prevents the icon from being stretched or letterboxed.
- Outlined text: if the mark contains letters, convert them to paths. A favicon is loaded as an image, and an image-context SVG cannot reliably load web fonts or other external resources, so live text may fall back to a different font.
- Self-contained file: remove references to external images, stylesheets and scripts. Scripts do not run when SVG is used as an image.
- True vector content: a .svg extension does not prove the file is vector. Open it and check that it is not simply wrapping an embedded raster image, which defeats the purpose and can bloat the file.
- Correct MIME type: the server should deliver the file as image/svg+xml. Next.js handles this for files in app and public.
Design recommendations for small sizes
- Use a reduced mark: a symbol, monogram or single letter usually works better than a full wordmark or lockup.
- Refine to a pixel grid: set the viewBox to a small whole-number grid and snap major edges and straight strokes to whole units. This alignment reduces anti-aliasing blur, the soft gray edges a renderer produces when a line falls between pixels.
- Thicken thin strokes and open up tight counters: counters are the enclosed or partly enclosed spaces inside letterforms, and they fill in quickly at small sizes.
- Limit colors and gradients: flat, high-contrast fills hold up better than subtle tonal changes.
- Check the result visually at actual size, not only zoomed in inside a design tool.
Optional: adapting to dark mode
Because SVG can contain CSS, the icon can change color based on the system theme using a prefers-color-scheme media query inside the file. Browsers differ in whether they apply this to favicons, so treat it as an enhancement and make sure the default colors are legible on both light and dark tab backgrounds.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<style>
path { fill: #111111; }
@media (prefers-color-scheme: dark) {
path { fill: #ffffff; }
}
</style>
<path d="M4 4h24v24H4z" />
</svg>
The namespace attribute in the root svg element is a standard XML identifier that every SVG requires; it is not a link the browser fetches. The square path is a placeholder for your own artwork.
Cleaning the export
Design applications often add editor metadata, hidden layers, unused definitions and excessive decimal precision. Remove these with an SVG optimizer or by hand, then reopen the file to confirm the shapes still render correctly, since aggressive optimization can merge or distort paths.
Browser support and fallbacks
SVG favicons are not supported in every browser, and support has historically been weakest in Safari and in older browser versions. No current support data was supplied for this guide, so check an up-to-date compatibility reference before relying on SVG alone. Keeping a favicon.ico fallback, and an apple-icon PNG if you want a home-screen icon on Apple devices, is the safe default.
Verifying the result
- Inspect the page head in your browser's developer tools and confirm a link tag points to the SVG with type image/svg+xml.
- Open the SVG path directly in the browser and confirm it loads without errors.
- Hard-refresh or open a private window. Browsers cache favicons aggressively, so an old icon may persist after a correct change.
- View the tab in both light and dark browser themes.
- Test in at least one browser that does not render SVG favicons and confirm the fallback appears.
- Run a production build and check the deployed site, not only the development server.
A note on rights
Having a logo file, in any format, does not grant permission to use it. Use a favicon only for a brand you own or are authorized to represent, and follow any brand guidelines that restrict how the mark may be simplified or recolored.