If your Express app shows a blank tab icon, the file may exist but never be served publicly or linked in the page head. This Express JS favicon guide uses static middleware and standard HTML links.

Prerequisites

Prepare a square brand mark. Mzu favicondl can create an SVG, an ICO fallback, and an optional Apple touch PNG.

You also need:

Express JS favicon setup

  1. Create a public directory

    Place browser-facing assets in public at the project root:

    my-app/
    ├─ public/
    │  ├─ favicon.svg
    │  ├─ favicon.ico
    │  ├─ apple-touch-icon.png
    │  └─ index.html
    └─ app.js

    Keep filenames exact because Linux servers distinguish uppercase and lowercase characters.

  2. Serve the public directory

    Register static middleware before application routes and any catch-all 404 handler:

    const express = require('express');
    const path = require('path');
    
    const app = express();
    
    app.use(express.static(path.join(__dirname, 'public')));
    
    app.listen(3000, () => {
      console.log('Listening on http://localhost:3000');
    });

    Express now maps public/favicon.svg to /favicon.svg and can serve public/index.html at /. A route placed before static middleware can answer the icon request first.

  3. Link the icons in the HTML head

    Add explicit links to the shared layout so every route receives them:

    <head>
      <link rel='icon' href='/favicon.svg' type='image/svg+xml'>
      <link rel='icon' href='/favicon.ico' sizes='16x16 32x32 48x48'>
      <link rel='apple-touch-icon' href='/apple-touch-icon.png'>
    </head>

    The HTML Standard defines rel='icon' as an external resource link, so these tags give browsers an explicit icon URL.

  4. Verify the files and rendered HTML

    Restart the server, then request both files:

    curl -I http://localhost:3000/favicon.svg
    curl -I http://localhost:3000/favicon.ico

    Both requests should return HTTP 200. Confirm that the page source contains the same paths; if the files respond but the tab still looks wrong, use the favicon troubleshooting checklist.

  5. Publish icon updates safely

    When the icon changes, update the HTML URL to href='/favicon.svg?v=2' and increment the version on each deployment. A filename hash also works and avoids reusing the old URL; the cache-busting guide explains the trade-offs.

Common Express pitfalls

Conclusion

Keep the asset path, static middleware, and shared HTML links aligned. That gives every Express route the same favicon without a dedicated icon controller.