If you've ever launched a new project and realized your browser tab still shows that generic purple Gatsby logo, you're not alone. It's the ultimate 'I just finished the tutorial' look. While Gatsby is incredibly powerful for performance, its file-based structure can make simple tasks like adding a favicon for gatsby site feel more complicated than they need to be.

We have all been there: you drop a favicon.ico into the root, refresh three times, and... nothing happens. That is because Gatsby's build process handles assets differently than a standard HTML site. To get a professional result like Stripe or GitHub, you need a strategy that handles multiple resolutions and PWA requirements automatically.

The Best Way: Using gatsby-plugin-manifest

In 2026, the gold standard is still gatsby-plugin-manifest. Why? Because it doesn't just add one icon; it generates a whole suite of sizes for Android, iOS, and desktop browsers. It also creates the manifest.webmanifest file, which is critical if you want your site to be installable as a web app. You can learn more about this in our guide on mastering favicon site.webmanifest.

Step 1: Install the Plugin

First, ensure you have the plugin installed in your project. Most Gatsby starters include it by default, but it's worth checking your package.json.

npm install gatsby-plugin-manifest

Step 2: Configure gatsby-config.js

This is where the magic happens. You need to point the plugin to a high-resolution source image (at least 512x512 pixels). The plugin will then downsample this image into all the required formats during the build process.

module.exports = {
  plugins: [
    {
      resolve: 'gatsby-plugin-manifest',
      options: {
        name: 'My Gatsby Site',
        short_name: 'GatsbySite',
        start_url: '/',
        background_color: '#ffffff',
        theme_color: '#663399',
        display: 'minimal-ui',
        icon: 'src/images/icon.png', // Path to your source icon
      },
    },
  ],
}

Step 3: Verify the Output

When you run gatsby build, look in your public folder. You will see a dozen different PNG files and a manifest file. This automated approach ensures that whether a user is on a high-DPI Mac or an old Android phone, your icon looks crisp. (Pro tip: always use a square PNG for the source to avoid weird stretching).

The Manual Method: Using the Static Folder

Sometimes you don't want the plugin to touch your icons. Maybe you have a very specific, hand-optimized .ico file or an SVG that you want to serve directly. In this case, use the static folder at the root of your project.

Why use the static folder?

Anything placed in the /static folder is copied directly to the /public folder without being processed by Webpack. If you put favicon.ico in /static/favicon.ico, it will be available at yourdomain.com/favicon.ico. This is the 'old school' way, but it works perfectly for simple needs.

Adding the Link Tag

To make it official, you need to tell the browser where the icon is. Since Gatsby uses React, you'll likely use a SEO component or Gatsby Head API to inject the link tag into your HTML head.

export const Head = () => (
  <>
    <link rel="icon" href="/favicon.ico">

)

Common Pitfalls to Avoid

Even with these tools, things can go wrong. Here are the three most common issues I see in production environments:

At the end of the day, your favicon is the 'face' of your tab. Taking ten minutes to set up gatsby-plugin-manifest correctly makes the difference between a site that looks like a hobby project and one that looks like a professional brand. If you need to generate those high-res source images quickly, tools like Mzu favicondl can help you convert your logo into the perfect 512x512 PNG to start the process.