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

  1. // ==UserScript==
  2. // @name Custom Font Override (Flexible Edition)
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.00
  5. // @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
  6. // @author You
  7. // @match *://*/*
  8. // @grant none
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. // --- Font Customization Options ---
  16. // Users can tweak these to set their preferred font source
  17. 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"};
  18. // useGoogleFonts: True = use Google Fonts CSS (default); False = check other options
  19. // googleFontUrl: Default Roboto Google Fonts CSS link (third <link> from embed code)
  20. // googleFontName: Font name for Google Fonts (default: "Roboto")
  21. // useCustomUrl: True = use a custom online font file; False = use local if useGoogleFonts is also false
  22. // customFontName: Name for your custom online font (e.g., "MyFont")
  23. // customFontUrl: Direct URL to a font file (e.g., .woff2); empty by default
  24. // localFontName: Local font name if both useGoogleFonts and useCustomUrl are false
  25. // fallback: Fallback font if all else fails (default: "sans-serif")
  26.  
  27. // --- How to Customize This Script ---
  28. // Option 1: Use Google Fonts (Default: Roboto)
  29. // - Keep useGoogleFonts: true
  30. // - Visit fonts.google.com, pick a font, select styles (e.g., weights, italics), click "Get font"
  31. // - 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")
  32. // - Paste it into googleFontUrl, update googleFontName to match (e.g., "Open Sans")
  33. // - Set useCustomUrl: false
  34. //
  35. // Option 2: Use a Custom Online Font File (e.g., .woff2)
  36. // - Set useGoogleFonts: false and useCustomUrl: true
  37. // - Set customFontName to your font’s name (e.g., "MyCoolFont")
  38. // - Set customFontUrl to a direct .woff2 file URL (e.g., "https://example.com/mycoolfont.woff2")
  39. // - .woff2 is recommended for speed and mobile compatibility—faster loading!
  40. // - Example: Roboto .woff2: "https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxKKTU1Kg.woff2"
  41. //
  42. // Option 3: Use a Local Font Installed on Your Computer
  43. // - Set useGoogleFonts: false and useCustomUrl: false
  44. // - Update localFontName to your font’s exact name (e.g., "Arial", "Times New Roman", "Comic Sans MS")
  45. // - Check the name in Windows (Settings > Fonts) or macOS (Font Book)
  46.  
  47. function applyFontOverride() {
  48. // Determine and log the active font source
  49. const activeFont = fontSettings.useGoogleFonts ? fontSettings.googleFontName : fontSettings.useCustomUrl ? fontSettings.customFontName : fontSettings.localFontName;
  50. console.log(`Starting font override with ${activeFont}`);
  51.  
  52. // --- Load Font Based on Selected Option ---
  53. if (fontSettings.useGoogleFonts) {
  54. console.log("Loading Google Fonts CSS: " + fontSettings.googleFontUrl);
  55.  
  56. // Preconnect to fonts.googleapis.com
  57. const linkPreconnect1 = document.createElement('link');
  58. linkPreconnect1.rel = "preconnect";
  59. linkPreconnect1.href = "https://fonts.googleapis.com";
  60. document.head.appendChild(linkPreconnect1);
  61. console.log("Added preconnect to https://fonts.googleapis.com");
  62.  
  63. // Preconnect to fonts.gstatic.com with crossorigin
  64. const linkPreconnect2 = document.createElement('link');
  65. linkPreconnect2.rel = "preconnect";
  66. linkPreconnect2.href = "https://fonts.gstatic.com";
  67. linkPreconnect2.setAttribute("crossorigin", "");
  68. document.head.appendChild(linkPreconnect2);
  69. console.log("Added preconnect to https://fonts.gstatic.com");
  70.  
  71. // Load the Google Fonts stylesheet
  72. const linkStylesheet = document.createElement('link');
  73. linkStylesheet.rel = "stylesheet";
  74. linkStylesheet.href = fontSettings.googleFontUrl;
  75. document.head.appendChild(linkStylesheet);
  76. console.log("Added stylesheet link: " + fontSettings.googleFontUrl);
  77. } else if (fontSettings.useCustomUrl && fontSettings.customFontUrl) {
  78. console.log("Loading custom font file: " + fontSettings.customFontUrl);
  79. const fontFaceStyle = document.createElement('style');
  80. fontFaceStyle.textContent = `
  81. @font-face {
  82. font-family: "${fontSettings.customFontName}";
  83. src: url("${fontSettings.customFontUrl}") format("woff2");
  84. }
  85. `;
  86. document.head.appendChild(fontFaceStyle);
  87. } else {
  88. console.log("Using local font: " + fontSettings.localFontName);
  89. }
  90.  
  91. // --- Apply Font Styles ---
  92. const style = document.createElement('style');
  93. style.type = 'text/css';
  94. let cssContent = '';
  95.  
  96. // Apply the selected font to all common text elements
  97. const fontName = fontSettings.useGoogleFonts ? fontSettings.googleFontName : fontSettings.useCustomUrl ? fontSettings.customFontName : fontSettings.localFontName;
  98. cssContent += `
  99. /* Apply ${fontName} to all common text elements */
  100. body, p, h1, h2, h3, h4, h5, h6, span, div, a, li, td, th, input, textarea, select, option, label, button, i, em {
  101. font-family: "${fontName}", ${fontSettings.fallback} !important;
  102. }
  103. `;
  104.  
  105. // --- Icon and Navigation Preservation ---
  106. // These rules ensure icons and navigation stay intact
  107. cssContent += `
  108. /* Preserve generic icon fonts so they don’t get overridden */
  109. [class*="icon-"], [class*="mdi-"], svg {
  110. font-family: inherit !important;
  111. }
  112.  
  113. /* Keep Glyphicons working (e.g., home icon) */
  114. .glyphicon,
  115. [class*="glyphicon-"] {
  116. font-family: "Glyphicons Halflings" !important;
  117. }
  118.  
  119. /* Protect Font Awesome icons (e.g., gear, menu) across versions */
  120. span.fa,
  121. span[class*="fa-"],
  122. i.fa,
  123. i[class*="fa-"] {
  124. font-family: "FontAwesome", "Font Awesome 5 Free", "Font Awesome 5 Pro", "Font Awesome 6 Free", "Font Awesome 6 Pro" !important;
  125. }
  126.  
  127. /* Preserve Material Icons (e.g., menu from Google’s set) */
  128. .material-icons,
  129. [class*="material-icons"] {
  130. font-family: "Material Icons" !important;
  131. }
  132.  
  133. /* Preserve Icomoon icons (e.g., custom .icon classes) */
  134. i.icon:not([class*="fa-"]):not([class*="glyphicon-"]):not([class*="material-icons"]):not([class*="mdi-"]) {
  135. font-family: "icomoon" !important;
  136. }
  137.  
  138. /* Ensure NavTabs navigation icons don’t break */
  139. #NavTabs *:not(.glyphicon):not([class*="glyphicon-"]):not(.fa):not([class*="fa-"]):not(.material-icons):not([class*="material-icons"]):not(.icon):not([class*="icon-"]) {
  140. font-family: inherit !important;
  141. }
  142. `;
  143.  
  144. style.textContent = cssContent;
  145. document.head.appendChild(style);
  146.  
  147. console.log("Font override applied successfully with " + fontName + "; Icon preservation for Glyphicons, Font Awesome, Material Icons, Icomoon");
  148. }
  149.  
  150. // --- Run the Function on Page Load ---
  151. window.addEventListener('load', applyFontOverride);
  152. applyFontOverride();
  153. })();