1

When the browser is in incognito mode, the tab is black. It can make the favicon either not super visible, or even invisible in worst case. This isn't great. I've seen some post offering a way to detect the dark mode and change the favicon accordingly but after tries : incognito mode isn't detected as dark mode. Beside, some people offered ways to detect incognito mode with javascript, but they're apparently not reliable at all.

Does anyone has a reliable way to handle that? (beside making the favicon colors as visible in light and dark)

Thank you

FTW
  • 922
  • 1
  • 7
  • 19
  • Does this answer your question? [Detect if the browser is using dark mode and use a different favicon](https://stackoverflow.com/questions/55170708/detect-if-the-browser-is-using-dark-mode-and-use-a-different-favicon) – Komeil Mehranfar Jun 10 '23 at 16:46
  • No, this is about dark mode, I'm talking about incognito – FTW Jun 11 '23 at 06:24

2 Answers2

0

For your solution you can create 2 functions To detect Dark Mode: isDarkMode To Detect incognito Mode : isIncognitoMode

here is the code you can refer :

function isDarkMode() {
    return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
}

function isIncognitoMode() {
    return new Promise(function(resolve) {
        try {
            localStorage.setItem('IncognitoMode', 'true');
            localStorage.removeItem('IncognitoMode');
            resolve(false);
        } catch (e) {
            resolve(true);
        }
    });
}

function isIncognitoAndDarkMode() {
    return Promise.all([isDarkMode(), isIncognitoMode()]).then(function([darkMode, incognitoMode]) {
        return darkMode && incognitoMode;
    });
}

use isIncognitoAndDarkMode function to get your output

hiren207
  • 184
  • 6
  • Thank you, don't you mean isIncognitoORDarkMode (with associated modifs, but I can do that)? – FTW Jun 10 '23 at 08:14
  • Is there btw a reason you made it in promises? – FTW Jun 10 '23 at 08:17
  • That's because we are using javascript script and By utilizing promises and async/await, we can handle asynchronous operations in a more readable and sequential manner or else we have to use callback mechanism for the same – hiren207 Jun 10 '23 at 20:47
  • I understand that but which part is supposed to be asynchronous in this context? – FTW Jun 11 '23 at 06:23
  • On a side note : this localStorage technique seems a bit erratic unfortunately. It seemed to work at first, and suddenly, not anymore. I don't know why but regardless, some browser apparently allow localstorage in incognito mode, and clear it after closing the tab. Considering that, I can't validate this answer sorry. – FTW Jun 11 '23 at 08:18
0

Okay I'm using this package for reliable (apparently) incognito mode detection : https://github.com/Joe12387/detectIncognito, and

window.matchMedia('(prefers-color-scheme: dark)');

For the dark mode.

In the html I have :

<link class="favicon" rel="icon" href="/icons/favicon.ico" />
<link class="favicon" rel="apple-touch-icon" sizes="57x57" href="/icons/apple-icon-57x57.png" />
<link class="favicon" rel="apple-touch-icon" sizes="60x60" href="/icons/apple-icon-60x60.png" />
<link class="favicon" rel="apple-touch-icon" sizes="72x72" href="/icons/apple-icon-72x72.png" />

(notice the class)

Then in a js file :

import { detectIncognito } from 'detectincognitojs';

const matcher = window.matchMedia('(prefers-color-scheme: dark)');

class FaviconService {
    isIncognitoMode() {
        return detectIncognito();
    }

    isDarkMode() {
        return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
    }

    async isIncognitoOrDarkMode() {
        return Promise.all([this.isDarkMode(), this.isIncognitoMode()]).then(function ([
            darkMode,
            incognitoModeResult,
        ]) {
            return darkMode || incognitoModeResult.isPrivate;
        });
    }

    getFaviconLinks() {
        return document.getElementsByClassName('favicon');
    }

    setFaviconsForLightMode() {
        const links = this.getFaviconLinks();

        for (const link of links) {
            link.href = link.href.replace('/dark-icons/', '/icons/');
        }
    }

    setFaviconsForDarkMode() {
        const links = this.getFaviconLinks();

        for (const link of links) {
            link.href = link.href.replace('/icons/', '/dark-icons/');
        }
    }

    async updateFavicons() {
        const ret = await this.isIncognitoOrDarkMode();
        if (ret) {
            this.setFaviconsForDarkMode();
        } else {
            this.setFaviconsForLightMode();
        }
    }

    setup() {
        matcher.addEventListener('change', () => {
            this.updateFavicons();
        });
    }
}

export default new FaviconService();

Then where I init my things (depending on the framework)

FaviconService.setup();
FaviconService.updateFavicons();

It works great. Tested on chrome, firefox, edge.

FTW
  • 922
  • 1
  • 7
  • 19