Mayank
Mayank

Mayank

Customizing the new MDN redesign

Customizing the new MDN redesign

Mayank's photo
Mayank
ยทMar 3, 2022ยท

3 min read

The redesign for MDN web docs went live yesterday. But what's a redesign if not polarizing? Just look at the comments on their twitter and github.

Problems

Personally, I mostly like it, even if only for the inclusion of dark mode. From my initial experience, I've found only two things that I would change:

  • Currently, the dark mode uses hsl(250deg 13% 9%) as the background color, which creates a bit too much contrast.
  • The new browser compatibility section doesn't present enough information at first glance.

And I'm not the only one who finds both of those things problematic. There have already been github issues created: mdn/yari#5378 and mdn/yari#5366.

image.png

Solutions

So while these issues will probably get fixed, we don't need to wait. With the help of browser extensions, we can take matters into our own hands. I'm going to show you what I did, but you can easily extend this approach to do all kinds of fancy stuff.

CSS: Changing the background color

I already use the Stylus extension to inject userstyles into many websites, so this one was extremely simple.

All I needed to do is slightly change the value of the --background-primary CSS variable.

:root {
  --background-primary: hsl(250deg 15% 20%);
}

Like every other frontend developer, I love caniuse.com, so I thought "why not just include a link to caniuse in the MDN page?"

So I wrote a userscript that I am injecting into MDN pages using Tampermonkey. I will include the code below, but all it does is:

  1. search the MDN page title on caniuse.com
  2. get the url to the top search result
  3. visit the url and parse the browser compatibility percentage
  4. on the MDN page, add an anchor element that links to the above url and displays the percentage

Here's what the result looks like:

image.png

And here's the code (feel free to modify it as you see fit):

// ==UserScript==
// @name         Add caniuse link to MDN docs
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  searches the feature name on caniuse and adds the % and link to the BC section
// @author       You
// @match        https://developer.mozilla.org/en-US/docs/Web/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=mozilla.org
// @grant        GM_xmlhttpRequest
// @grant        window.onurlchange
// @connect      caniuse.com
// ==/UserScript==

(async function () {
  'use strict';

  async function addCaniuseLink() {
    const browserCompatHeading = document.querySelector('#browser_compatibility');
    if (!browserCompatHeading) return;

    const featureName = window.location.pathname.split('/').at(-1);
    const searchUrl = `https://caniuse.com/process/query.php?search=${encodeURIComponent(featureName)}`;

    const caniuseUrl = await new Promise((resolve, reject) => {
      GM_xmlhttpRequest({
        url: searchUrl,
        method: 'GET',
        onload: ({ response, status, responseType }) => {
          if (status !== 200) reject('oopsie');
          resolve(`https://caniuse.com/${JSON.parse(response).featureIds[0]}`);
        },
      });
    });

    const compatPercent = await new Promise((resolve, reject) => {
      GM_xmlhttpRequest({
        url: caniuseUrl,
        method: 'GET',
        onload: ({ response, status, responseType }) => {
          if (status !== 200) reject('oopsie');
          const dom = (new DOMParser()).parseFromString(response, 'text/html');
          resolve(dom.querySelector('.support').textContent);
        },
      });
    });

    const caniuseElement = `
      <a
        class='external'
        href=${caniuseUrl}
        style='font-size: 1.5rem; font-weight: 300; line-height: 1.5; position: absolute; inset-inline-end: 0; display: inline-flex; align-items: baseline; color: var(--text-secondary);'
      >
        <span style='font-size: 0.8rem; margin-inline-end: 0.25rem;'>caniuse</span>
        ${compatPercent}
      </a>
    `;

    browserCompatHeading.style.position = 'relative';
    browserCompatHeading.insertAdjacentHTML('beforeend', caniuseElement);
  }

  await addCaniuseLink();
  window.addEventListener('urlchange', addCaniuseLink);
})();

Conclusion

And there you have it. Hopefully goes without saying but this approach of modifying websites on your end is very fragile. Your code will probably break in the future, especially if the site gets updated regularly. But I choose to do it anyway just because it's fun. ๐Ÿ˜…