change favicon on incognito mode

550 Views Asked by At

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

2

There are 2 best solutions below

0
FTW On BEST ANSWER

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.

5
hiren207 On

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