DEV Community

Jakub T. Jankiewicz
Jakub T. Jankiewicz

Posted on • Edited on

11

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.

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
type FaviconProps = {
    name: string;
};

const Favicon = ({ name }: FaviconProps): 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={name}/>
            <meta name="msapplication-TileColor" content="#ffc40d"/>
            <meta name="theme-color" content="#ffffff"/>
        </>
    );
}

export default Favicon;
Enter fullscreen mode Exit fullscreen mode

You may need to close each tags, so they are a proper JSX.

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.

You also need to provide the name of your app in the name prop.

// /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 name="My Awesome Page"/>
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;
Enter fullscreen mode Exit fullscreen mode

And that's it. If you want some better performance you can use compression when generating favicon.

If you like this post, you can follow me on twitter at @jcubic and check my home page.

And here you can find some NextJS jobs.

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (0)

👋 Kindness is contagious

Immerse yourself in a wealth of knowledge with this piece, supported by the inclusive DEV Community—every developer, no matter where they are in their journey, is invited to contribute to our collective wisdom.

A simple “thank you” goes a long way—express your gratitude below in the comments!

Gathering insights enriches our journey on DEV and fortifies our community ties. Did you find this article valuable? Taking a moment to thank the author can have a significant impact.

Okay