Set Up Next.js Favicons with Just 3 Files


TL;DR

Essential Favicons Setup

For a quick and efficient favicon setup in Next.js, you only need these three files:

  1. favicon.ico

    • Purpose: The classic favicon displayed in browser tabs.
    • Placement: Place a 32×32 favicon.ico file in the app directory. Next.js will automatically serve it at /favicon.ico.
  2. icon.svg

    • Purpose: Modern browsers prefer SVG icons for scalability and crispness.

    • Placement: Save your SVG icon as icon.svg in the public directory.

    • Usage in Next.js Metadata:

         {
           rel: 'icon',
           url: '/icon.svg',
           type: 'image/svg+xml',
         }
      
      
  3. apple-touch-icon

    • Purpose: Used when users add your website to their iOS home screen.

    • Placement: Add a 180×180 PNG named apple-touch-icon.png to the public directory.

    • Usage in Next.js Metadata:

         {
           rel: 'apple-touch-icon',
           sizes: '180x180',
           url: '/apple-touch-icon.png',
         }
      

Note:

  • The app directory in Next.js 13 (using the App Router) is special because placing a favicon.ico file at the root of this directory ensures it's automatically served at /favicon.ico without additional configuration.
  • The public directory is ideal for other static assets because it's served at the root (/) of your application, making it straightforward to reference these files in your code.

This minimal setup ensures compatibility with most browsers and devices, providing essential icon support without unnecessary complexity.


Expanded Setup for PWA Support

If your app is a Progressive Web App (PWA), you'll need to define additional icons in a manifest.webmanifest file. This enhances the user experience when your app is installed on a device.

Additional Icons for PWAs

  1. 192×192 PNG

    • Purpose: Used for Android home screen icons and in notifications.
    • Placement: Save as icon-192.png in the public directory.
  2. 512×512 PNG

    • Purpose: The default icon for splash screens when the app is launched.
    • Placement: Save as icon-512.png in the public directory.
  3. 512×512 Maskable PNG

    • Purpose: Ensures proper display on devices that apply masks to icons (e.g., Android devices with non-rectangular shapes).
    • Placement: Save as icon-maskable.png in the public directory.
    • Design Consideration: Include extra padding. The safe area for a maskable icon is a central circle of 409×409 pixels inside the 512×512 canvas. Use tools like maskable.app to adjust the padding correctly.

Example Manifest File

Create a manifest.webmanifest file in the public directory:

{
  "name": "Your App Name",
  "short_name": "App",
  "start_url": ".",
  "display": "standalone",
  "background_color": "#FFFFFF",
  "description": "Your app description",
  "icons": [
    { "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" },
    {
      "src": "/icon-maskable.png",
      "type": "image/png",
      "sizes": "512x512",
      "purpose": "maskable"
    },
    { "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" }
  ]
}

HTML Reference for Non-Next.js Apps

If you're not using Next.js, include the following in your <head>:

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

Generating the favicon.ico File

To generate the .ico file with both 32×32 and 16×16 resolutions, use ImageMagick:

magick icon.svg -resize 32x32 icon-32.png
magick icon.svg -resize 16x16 icon-16.png
magick icon-32.png icon-16.png favicon.ico

Place the generated favicon.ico in your application's root directory.


Optional: Theming with Media Queries

For advanced theming, you can define light and dark mode icons using media queries in the metadata.icons array:

export const metadata = {
  icons: [
    {
      rel: 'icon',
      media: '(prefers-color-scheme: light)',
      url: '/icon-light.svg',
      type: 'image/svg+xml',
    },
    {
      rel: 'icon',
      media: '(prefers-color-scheme: dark)',
      url: '/icon-dark.svg',
      type: 'image/svg+xml',
    },
  ],
}

This setup automatically displays the appropriate icon based on the user's system settings, enhancing user experience by aligning with their preferred theme.


Understanding the Purpose of Each Icon

favicon.ico

  • Purpose: The default icon displayed in browser tabs and bookmarks.
  • Why It's Needed: Provides brand recognition and improves user experience by allowing users to quickly identify your site among multiple tabs.
  • Placement in Next.js: Place it in the app directory root. Next.js will automatically serve it at /favicon.ico.

icon.svg

  • Purpose: A scalable icon for modern browsers, ensuring crisp display on all devices.
  • Why It's Needed: SVGs scale without loss of quality, making them ideal for high-resolution displays.
  • Placement: Place in the public directory.

apple-touch-icon.png

  • Purpose: Used when iOS users add your website to their home screen.
  • Why It's Needed: Ensures your app icon looks professional and recognizable on iOS devices.
  • Placement: Place in the public directory.

SEO and Accessibility Considerations

  • Brand Recognition: Consistent and professional icons improve brand visibility across devices and platforms.
  • User Experience: Properly sized and formatted icons ensure a seamless experience, whether users are browsing, bookmarking, or adding your app to their home screen.
  • Accessibility: High-quality icons with appropriate sizes enhance readability and usability for all users.

Troubleshooting Tips

  • Browser Caching: Browsers often cache favicons and may not immediately reflect updates.

    Solution: Instruct users (or yourself during testing) to clear the browser cache or perform a hard refresh (usually Ctrl+F5 or Cmd+Shift+R).

  • Incorrect File Paths: Ensure that your icon files are placed in the correct directories and that the paths in your code match.

  • Missing Sizes or Types: Omitting sizes or type attributes can lead to browsers ignoring your icons.

    Solution: Always specify the sizes and type attributes in your metadata or HTML tags.


Additional Resources


Recap: All the Icons You Need

Here's a summary of all the icons and their configurations for a fully functional setup:

Files to Include

  • favicon.ico: 32×32 (placed in app/ directory)
  • icon.svg: Scalable SVG icon (placed in public/ directory)
  • apple-touch-icon.png: 180×180 PNG (placed in public/ directory)
  • icon-192.png: 192×192 PNG (for Android home screens)
  • icon-512.png: 512×512 PNG (for splash screens)
  • icon-maskable.png: 512×512 PNG with padding (for maskable icons)

Next.js Metadata Example

{
  "icons": [
    {
      rel: 'icon',
      url: '/icon.svg',
      type: 'image/svg+xml',
    },
    {
      rel: 'apple-touch-icon',
      sizes: '180x180',
      url: '/apple-touch-icon.png',
    },
    // Only required for PWA apps.
    {
      rel: 'manifest',
      url: '/manifest.webmanifest',
    },
  ]
}

Make it Even Easier with SSK

If all of this sounds like a lot to manage, you can use StartupStarterKits.com to configure your favicons and PWA icons automatically. SSK-Core handles these details, allowing you to focus on building your app.


Conclusion

Setting up favicons in Next.js with just three files is straightforward and ensures your app has a professional look across different browsers and devices. By following this guide, you provide essential icon support without unnecessary complexity, enhancing both usability and brand recognition.


Cheers,
Tómas