Next.js: favicon, SVG icon, Apple & Chrome icons

Next.js: favicon, SVG icon, Apple & Chrome icons

November 13, 2023 by Dave Gray📖 5 min read

I began discussing Next.js Metadata in my last blog post, and I set up some basic information for my blog. That said, there are still a few areas to take a deeper dive on and the first is how to handle favicon and icon requirements.

Next.js Favicons

The Next.js docs on Metadata Files provided guidance. However, I also wanted to find general recommendations for these icon files on the web.

Fortunately, I discovered an in-depth article titled Definitive edition of "How to Favicon" in 2023 by Masa Kudamatsu. It could be my background in higher education, but I liked this article very much as Kudamatsu cited references from his research throughout his writing.

According to Kudamatsu, we need the following in the <head> element of our web pages:

<link rel="icon" href="/favicon.ico" sizes="48x48" >
<link rel="icon" href="/favicon.svg" sizes="any" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
<link rel="manifest" href="/site.webmanifest" />

Kudamatsu has specific reasons for each link above. Most interesting is his recent August 2023 update for using sizes="48x48" on the favicon.ico. I won't dive into it here, but I highly recommend reading the article.

As of this writing in November 2023, I wanted to see if Next.js could provide Kudamatsu's recommendations for favicons. I found that it can, and I'll provide how I got there.

The Next.js Metadata Files docs provide two ways to set app icons:

  1. Using image files
  2. Using code to generate an icon

Generate an Icon

Of course, I wanted to use code to generate an icon or icons if I could. However, I found the docs later state under a Good to know footnote that you cannot generate a favicon icon.

Nevertheless, I tried the provided code in the docs for creating an icon.tsx in my app directory. It does generate an icon.

Here is the icon I found in the <head> of my page when using the icon.tsx file to generate an icon:

<link rel="icon" href="/icon?064c227bb33add9b" type="image/png" sizes="32x32">

So that was worth a try, but I quickly decided to go the image files route instead.

Using Image Files

Step One: Create an SVG Icon

There are many tools you can use to create an SVG icon. I used Canva, but you can also use which is where I went after creating my SVG icon. No matter what tool you use, save the file as icon.svg so Next.js will recognize it.

Step Two: Generate the Remaining Icons

I took the SVG icon I created and uploaded it to which generated the other icons I needed:

  1. favicon.ico
  2. apple-touch-icon.png
  3. android-chrome-192x192.png
  4. android-chrome-512x512.png

It also generated a file named site.webmanifest, but I will show my own manifest file below. You can also discard any other generated files.

Step Three: Rename Files

Not all of the files listed above have names that are compatible with Next.js. Specifically, the apple-touch-icon.png needs to be renamed to apple-icon.png. I also renamed the android-chrome files to simply icon-192.png and icon-512.png, but that was my preference.

Step Four: Web Manifest

You need the Web Manifest to identify the two android-chrome icons. You won't see a direct link to these icons in the <head> element, but you will see a link to the manifest file.

The Next.js manifest docs allow for a static file or for a generated file. The manifest must be named manifest.json or manifest.webmanifest and be at the root level of the app directory.

I opted to generate my manifest with the function provided in the Next.js docs.

Here is what my manifest.ts file contains:

import { MetadataRoute } from 'next'

export default function manifest(): MetadataRoute.Manifest {
    return {
        name: 'Dave Gray Teaches Code',
        short_name: "Dave Gray",
        description: "Dave's Blog powered by Next.js",
        start_url: '/',
        display: 'standalone',
        background_color: '#1E283A',
        theme_color: '#1E283A',
        icons: [
                "src": "/images/icon-192.png",
                "sizes": "192x192",
                "type": "image/png"
                "src": "/images/icon-512.png",
                "sizes": "512x512",
                "type": "image/png"

If you are curious about the settings above, you can read the Web Manifest specs. If you leave some of these out, Lighthouse may complain when evaluating your site.

Note: You only need to provide info for the two android-chrome icons in this file as I did above.

Step Five: Where to Put Your Files

You should now have the following files in root of your app directory:

  1. favicon.ico
  2. icon.svg
  3. manifest.ts

And you should have the android-chrome icons in your public folder.

I'm using an images folder inside my public folder, so notice my manifest file has /images/icon-192.png. You do not have to specify your public folder as part of the file path in the manifest.

Step Six: Build Your App

Open a terminal window and type npm run dev.

Open up your Next.js app in your browser and inspect the <head> element.

You should now see the following links:

<link rel="manifest" href="/manifest.webmanifest">
<link rel="icon" href="/favicon.ico" type="image/x-icon" sizes="48x48">
<link rel="icon" href="/icon.svg?f4ac04897a3b2294" type="image/svg+xml" sizes="any">
<link rel="apple-touch-icon" href="/apple-icon.png?ebbb82dc3cc1b5eb" type="image/png" sizes="180x180">

Note: The manifest link may not be next to the icon links, but it should be in there somewhere.

With Kudamatsu updating his article to recommend the sizes="48x48" setting for the favicon.ico in August, I'm glad to see that is already reflected in how Next.js handles that file!


← Back to home

Last Updated on November 22, 2023