Custom Font Override (Flexible Edition)

Replaces website fonts with Roboto (default via Google Fonts), a local font, or a custom online URL, without breaking Font Awesome, Glyphicons, or Icomoon icons

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Custom Font Override (Flexible Edition)
// @namespace    http://tampermonkey.net/
// @version      1.00
// @description  Replaces website fonts with Roboto (default via Google Fonts), a local font, or a custom online URL, without breaking Font Awesome, Glyphicons, or Icomoon icons
// @author       You
// @match        *://*/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // --- Font Customization Options ---
    // Users can tweak these to set their preferred font source
    const fontSettings = {useGoogleFonts: true, googleFontUrl: "https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap", googleFontName: "Roboto", useCustomUrl: false, customFontName: "CustomFont", customFontUrl: "", localFontName: "Arial", fallback: "sans-serif"};
    // useGoogleFonts: True = use Google Fonts CSS (default); False = check other options
    // googleFontUrl: Default Roboto Google Fonts CSS link (third <link> from embed code)
    // googleFontName: Font name for Google Fonts (default: "Roboto")
    // useCustomUrl: True = use a custom online font file; False = use local if useGoogleFonts is also false
    // customFontName: Name for your custom online font (e.g., "MyFont")
    // customFontUrl: Direct URL to a font file (e.g., .woff2); empty by default
    // localFontName: Local font name if both useGoogleFonts and useCustomUrl are false
    // fallback: Fallback font if all else fails (default: "sans-serif")

    // --- How to Customize This Script ---
    // Option 1: Use Google Fonts (Default: Roboto)
    // - Keep useGoogleFonts: true
    // - Visit fonts.google.com, pick a font, select styles (e.g., weights, italics), click "Get font"
    // - Copy the third <link> URL from "Embed code in the <head> of your HTML" (e.g., "https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap")
    // - Paste it into googleFontUrl, update googleFontName to match (e.g., "Open Sans")
    // - Set useCustomUrl: false
    //
    // Option 2: Use a Custom Online Font File (e.g., .woff2)
    // - Set useGoogleFonts: false and useCustomUrl: true
    // - Set customFontName to your font’s name (e.g., "MyCoolFont")
    // - Set customFontUrl to a direct .woff2 file URL (e.g., "https://example.com/mycoolfont.woff2")
    // - .woff2 is recommended for speed and mobile compatibility—faster loading!
    // - Example: Roboto .woff2: "https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxKKTU1Kg.woff2"
    //
    // Option 3: Use a Local Font Installed on Your Computer
    // - Set useGoogleFonts: false and useCustomUrl: false
    // - Update localFontName to your font’s exact name (e.g., "Arial", "Times New Roman", "Comic Sans MS")
    // - Check the name in Windows (Settings > Fonts) or macOS (Font Book)

    function applyFontOverride() {
        // Determine and log the active font source
        const activeFont = fontSettings.useGoogleFonts ? fontSettings.googleFontName : fontSettings.useCustomUrl ? fontSettings.customFontName : fontSettings.localFontName;
        console.log(`Starting font override with ${activeFont}`);

        // --- Load Font Based on Selected Option ---
        if (fontSettings.useGoogleFonts) {
            console.log("Loading Google Fonts CSS: " + fontSettings.googleFontUrl);

            // Preconnect to fonts.googleapis.com
            const linkPreconnect1 = document.createElement('link');
            linkPreconnect1.rel = "preconnect";
            linkPreconnect1.href = "https://fonts.googleapis.com";
            document.head.appendChild(linkPreconnect1);
            console.log("Added preconnect to https://fonts.googleapis.com");

            // Preconnect to fonts.gstatic.com with crossorigin
            const linkPreconnect2 = document.createElement('link');
            linkPreconnect2.rel = "preconnect";
            linkPreconnect2.href = "https://fonts.gstatic.com";
            linkPreconnect2.setAttribute("crossorigin", "");
            document.head.appendChild(linkPreconnect2);
            console.log("Added preconnect to https://fonts.gstatic.com");

            // Load the Google Fonts stylesheet
            const linkStylesheet = document.createElement('link');
            linkStylesheet.rel = "stylesheet";
            linkStylesheet.href = fontSettings.googleFontUrl;
            document.head.appendChild(linkStylesheet);
            console.log("Added stylesheet link: " + fontSettings.googleFontUrl);
        } else if (fontSettings.useCustomUrl && fontSettings.customFontUrl) {
            console.log("Loading custom font file: " + fontSettings.customFontUrl);
            const fontFaceStyle = document.createElement('style');
            fontFaceStyle.textContent = `
                @font-face {
                    font-family: "${fontSettings.customFontName}";
                    src: url("${fontSettings.customFontUrl}") format("woff2");
                }
            `;
            document.head.appendChild(fontFaceStyle);
        } else {
            console.log("Using local font: " + fontSettings.localFontName);
        }

        // --- Apply Font Styles ---
        const style = document.createElement('style');
        style.type = 'text/css';
        let cssContent = '';

        // Apply the selected font to all common text elements
        const fontName = fontSettings.useGoogleFonts ? fontSettings.googleFontName : fontSettings.useCustomUrl ? fontSettings.customFontName : fontSettings.localFontName;
        cssContent += `
            /* Apply ${fontName} to all common text elements */
            body, p, h1, h2, h3, h4, h5, h6, span, div, a, li, td, th, input, textarea, select, option, label, button, i, em {
                font-family: "${fontName}", ${fontSettings.fallback} !important;
            }
        `;

        // --- Icon and Navigation Preservation ---
        // These rules ensure icons and navigation stay intact
        cssContent += `
            /* Preserve generic icon fonts so they don’t get overridden */
            [class*="icon-"], [class*="mdi-"], svg {
                font-family: inherit !important;
            }

            /* Keep Glyphicons working (e.g., home icon) */
            .glyphicon,
            [class*="glyphicon-"] {
                font-family: "Glyphicons Halflings" !important;
            }

            /* Protect Font Awesome icons (e.g., gear, menu) across versions */
            span.fa,
            span[class*="fa-"],
            i.fa,
            i[class*="fa-"] {
                font-family: "FontAwesome", "Font Awesome 5 Free", "Font Awesome 5 Pro", "Font Awesome 6 Free", "Font Awesome 6 Pro" !important;
            }

            /* Preserve Material Icons (e.g., menu from Google’s set) */
            .material-icons,
            [class*="material-icons"] {
                font-family: "Material Icons" !important;
            }

            /* Preserve Icomoon icons (e.g., custom .icon classes) */
            i.icon:not([class*="fa-"]):not([class*="glyphicon-"]):not([class*="material-icons"]):not([class*="mdi-"]) {
                font-family: "icomoon" !important;
            }

            /* Ensure NavTabs navigation icons don’t break */
            #NavTabs *:not(.glyphicon):not([class*="glyphicon-"]):not(.fa):not([class*="fa-"]):not(.material-icons):not([class*="material-icons"]):not(.icon):not([class*="icon-"]) {
                font-family: inherit !important;
            }
        `;

        style.textContent = cssContent;
        document.head.appendChild(style);

        console.log("Font override applied successfully with " + fontName + "; Icon preservation for Glyphicons, Font Awesome, Material Icons, Icomoon");
    }

    // --- Run the Function on Page Load ---
    window.addEventListener('load', applyFontOverride);
    applyFontOverride();
})();