DEV Community

Jakub T. Jankiewicz
Jakub T. Jankiewicz

Posted on • Updated on

Favicon for Next.js and TypeScript

I'm still learning Next.js and after having hard time to find out of the box solution to create favicon that will work everywhere, after done this myself, I've decided to create quick article about this.

What is favicon

Favicon is small icon that is usually shown in browser tab next to title of the site. Some Operating System display it differently, like Android or MacOS.

Best way to get Favicon that will just work

The best way to get favicon that will work on every device is to use generator that will do that for you.

I personally use Real Favicon Generator I trust that It create favicon for every possible use case.

To generate favicon you just upload an image. If you want best possible favicon you can generate one for MacOS and Windows that often need different background (those are

I personally always create favicon (that is just based on logo) in vector format (using Free Libre Open Source program Inkscape).

When you generate favicon remember to use /favicon directory.

Where to put the files

The files should be extracted into /public/ directory of Next.js project. So the files will be in in /public/favicon/. If you didn't use /favicon path when creating icons you will need to create one.

Next.js component

Now you need to add favicon that you've generated with Favicon Generator. The best idea is to create component called <Favicon/> that you can use in rest of the application:

// /compoponents/Favicon.tsx
const Favicon = (): JSX.Element => {
    return (
        <>
          {/* copy paste the html from generator */}
        </>
     );
}

export default Favicon;
Enter fullscreen mode Exit fullscreen mode

When you copy paste the html it will look similar to this:

// /compoponents/Favicon.tsx
const Favicon = (): JSX.Element => {
    return (
        <>
            <link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png"/>
            <link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png"/>
            <link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png"/>
            <link rel="manifest" href="/favicon/site.webmanifest"/>
            <link rel="mask-icon" href="/favicon/safari-pinned-tab.svg" color="#5bbad5"/>
            <meta name="apple-mobile-web-app-title" content="Snippit"/>
            <meta name="application-name" content="<APP NAME>"/>
            <meta name="msapplication-TileColor" content="#ffc40d"/>
            <meta name="theme-color" content="#ffffff"/>
        </>
    );
}

export default Favicon;
Enter fullscreen mode Exit fullscreen mode

Using component

To use new <Favicon/> component you need to update _document.tsx file.

Here is base document that you can use and extend. Or modify and just add <Favicon/> into <Head> tag.

// /pages/_document.tsx
import Document, { Head, Html, Main, NextScript, DocumentContext } from "next/document";

import Favicon from '../components/Favicon';

class MyDocument extends Document {
  static async getInitialProps(ctx: DocumentContext): Promise<Record<string, unknown> & {html: string}> {
    const initialProps = await Document.getInitialProps(ctx);
    return { ...initialProps };
  }

  render(): JSX.Element {
    return (
      <Html>
        <Head>
          <meta charSet="utf-8" />
          <Favicon/>
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;
Enter fullscreen mode Exit fullscreen mode

And that is. If you want some better performance you can use compression when generating favicon.

If you've liked this post, you can follow me on twitter at @jcubic.

Discussion (0)