Github recommendation blocker

Remove github's recommendation/trending cards in the dashboard thread. It's triggered by HTML change, usually takes 5ms in PC Chrome browser.

  1. // ==UserScript==
  2. // @name Github recommendation blocker
  3. // @namespace http://tampermonkey.net/
  4. // @version 2025-04-01
  5. // @description Remove github's recommendation/trending cards in the dashboard thread. It's triggered by HTML change, usually takes 5ms in PC Chrome browser.
  6. // @author dont-be-evil
  7. // @match https://github.com/
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=github.com
  9. // @grant none
  10. // @license GPLv3
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15. const keywords = ["Recommended for you", "Based on", "Popular among", "Popular projects among"];
  16.  
  17. const observer = new MutationObserver(mutations => {
  18. mutations.forEach(mutation => {
  19. mutation.addedNodes.forEach(node => {
  20. if (node.nodeType === 1) { // Ensure it's an element
  21. node.querySelectorAll('h5').forEach(h5 => {
  22. if (keywords.some(keyword => h5.textContent.includes(keyword))) {
  23. let parent = h5;
  24. for (let i = 0; i < 5; i++) {
  25. if (parent.parentElement) {
  26. parent = parent.parentElement;
  27. } else {
  28. return; // Exit if there are fewer than 5 ancestors
  29. }
  30. }
  31. parent.remove();
  32. }
  33. });
  34. }
  35. });
  36. });
  37. });
  38.  
  39. // Observe the whole document, including subtree modifications
  40. observer.observe(document, {
  41. childList: true,
  42. subtree: true
  43. });
  44.  
  45. // Function to observe shadow DOM elements
  46. function observeShadowRoots(node) {
  47. if (node.shadowRoot) {
  48. observer.observe(node.shadowRoot, { childList: true, subtree: true });
  49. }
  50. }
  51.  
  52. // Observe shadow DOM elements dynamically added
  53. const shadowObserver = new MutationObserver(mutations => {
  54. mutations.forEach(mutation => {
  55. mutation.addedNodes.forEach(node => {
  56. if (node.nodeType === 1) { // Ensure it's an element
  57. observeShadowRoots(node);
  58. }
  59. });
  60. });
  61. });
  62.  
  63. // Start observing for new shadow DOM elements
  64. shadowObserver.observe(document, {
  65. childList: true,
  66. subtree: true
  67. });
  68.  
  69.  
  70. })();