'Is it possible to make _document.tsx dynamic in NextJS?

I'm using React with NextJS. Now I want to place my favicon on the tabs conditional if the browser is in dark or in light mode. Is this anyhow possible?

_document.tsx:

class MyDocument extends Document {
  static async getInitialProps(ctx: DocumentContext) {
    const initialProps = await Document.getInitialProps(ctx);
    return { ...initialProps };
  }

  render() {
    return (
      <Html>
        <Head>
          <link
            rel="icon"
            type="image/png"
            sizes="32x32"
            href="/icons/favicon-32x32.png"
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

Tried to do it with a component like that and to implement this into the _document.tsx but it doesn`t work.

interface Props {
  rel: string;
  href: string;
  sizes: string;
  type?: string;
}

const IconHandling = (props: Props) => {
  const [dark, setDark] = useState<boolean>(false);

  useEffect(() => {
    if (
      window.matchMedia &&
      window.matchMedia('(prefers-color-scheme: dark)').matches
    ) {
      return setDark(true);
    } else {
      return setDark(false);
    }
  }, []);

  return (
    <link
      type={props.type}
      rel={props.rel}
      sizes={props.sizes}
      href={
        dark
          ? `../public/icons/light-${props.href}`
          : `../public/icons/${props.href}`
      }
    />
  );
};


Solution 1:[1]

React components outside of <Main /> will not be initialized by the browser according to the _document doc. Haven't found the official doc, but it seems that something similar happens to next/head.

It works if you write hooks outside Head in _app or a custom layout component:

import Head from 'next/head';
const IconHandling = (props: Props) => {
    const [dark, setDark] = useState<boolean>(false);
    useEffect(...);
    return <Head>...</Head>
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sin