Remixing other people's websites
Tags: ux, ui, javascript
Published: 2018-10-12 08:18:26

# Why would you want to change the UI of a site you visit?
Well, there're loads of reasons:
* Personalise your experience
* Remove unwanted content
* Add your own menu items
* Mock up UI improvements in the browser, record your results, and submit them
  as improvement suggestions to existing projects

...knock yourself out.

## Basic site modifications
The easiest code-free way to modify a site is just to remove unwanted elements from its pages. This can be done with code but often times that's overkill when you can just re-purpose an ad-blocker instead. I use [Ublock Origin](https://github.com/gorhill/uBlock/) for this.

While this is quick and easy, it only really allows you to remove things you're not interested in. You get a more tailored, streamlined experience but you don't get anything new.

### Example: remove clutter from [Microsoft office online](https://www.office.com).

So this:

![Office.com before](https://thepracticaldev.s3.amazonaws.com/i/x08cs31nyqdcaeb99twk.png)

Becomes this:

![Office.com after](https://thepracticaldev.s3.amazonaws.com/i/gv9f6uwse2zvqs4zkluv.png)

You can see I've ditched the hero image (which just meant that I had to scroll down on every page when I was using a laptop) and also removed the Office products I'm never going to use. Same goes with the upselling CTA links.

## Advanced site modification
Blocking elements is one thing, but adding functionality is a whole 'nother level.

For this, we're going to use "userscripts", little self-contained javascript snippets which trigger themselves automatically when the page URL matches a pattern.

With these scripts, you can perform a major overhaul of how a site behaves. You can hammer it into exactly the shape you want.

Now, userscripts have been around for a long time, and this might seem a little old-school in a world where web extensions are becoming easier and more portable. Why use such a crude tool? Well, because it's quick and easy and there's nothing to learn beyond normal everyday front-end Javascript. Why not use a [bookmarklet](https://en.wikipedia.org/wiki/Bookmarklet) I hear you ask? Automation and community, mostly.

## Some ideas to get you started

### Make your favourite site work at your favourite window size
Tired of using sites that aren't properly responsive?
* Remove unwanted elements (watch-list, news, everything in the sidebar, ads for
  IMDB Pro, the megamenu, etc.)
* Re-style the search form so it stays stuck to the top of the window
* Fix the width and padding issues that naively hiding the sidebar causes (see right hand side of "before" image)

So this:

![IMDB before](https://thepracticaldev.s3.amazonaws.com/i/gu408bs5nfu4ddpfrt0t.png)

Becomes this:

![IMDB after](https://thepracticaldev.s3.amazonaws.com/i/ji784urkdkdigk9zhyfq.png)


### Change pagination into infinite scroll
Do you prefer infinite scrolling?
* Write a function to load a page and inject part of it into the current page
* Hide the existing navigation
* Trigger the function on scroll if the page is at the bottom and there's
  a "next page" link to follow

### Fix sites which open every link in a new tab
Some sites (like Quora for example) insist on opening almost every link in a new tab. This breaks the way the web works and is something I personally find very annoying.

* bind to every anchor and prevent it from bubbling
* push the current URL into the browser's history
* update `window.location` directly

### Hide elements you can't block with a selector or xpath rule
Some websites use frameworks which produce "div soup" and don't have consistent class names or IDs. Sometimes this is just an artifact of the build process, other times it's a deliberate attempt to make it harder for people to detect and block unwanted content.

![Reddit](https://thepracticaldev.s3.amazonaws.com/i/cl4zjv1b8diro7q6atnq.png)

Let's say you're never interested in following the herd. You're on [Reddit](https://reddit.com) and you want a more distraction-free experience.

If you know an element includes the text "Trending communities".
* Write a function to check every div for the known text
* Work your way up its parent nodes until you reach the level you want to hide,
  and do so
* Flag every div you've checked so you don't check it again
* Re-trigger the script if the DOM is changed or with `setInterval()` if you have
  no better way.

## Tools
[Greasemonkey](https://www.greasespot.net/) was the original standard, but it's been surpassed now by [Tampermonkey](https://tampermonkey.net/) and [Violentmonkey](https://violentmonkey.github.io/about/). Despite the ominous name, I recommend Violentmonkey, because it's MIT-licensed.
Tampermonkey is currently the most popular userscript manager, but it's closed-source and can't guarantee your privacy. As far as effectiveness is concerned, it doesn't matter which one you use; they can all run userscripts and they all implement the original Greasemonkey API.

## API
The [Greasemonkey API](https://wiki.greasespot.net/Greasemonkey_Manual%3aAPI) allows you to do a bunch of things you might not normally be able to do, such as include arbitrary remote scripts. You don't need to know anything about it most of the time.

Many people use `@require` front matter to include jQuery, for example. You don't have to, I'm just sayin'.

## Sharing
There are public repositories of userscripts such as [Greasy Fork](https://greasyfork.org/) which are often a good place to get ideas.

## Safety
If you're going to use other peoples' userscripts, these plugins will let you examine them before installation, and there're obviously some constraints on what a script can actually do - but there's always the chance someone is distributing malicious code. Or, giving a little more benefit of the doubt, that their bug-ridden effort is going to have dangerous side-effects.

In reality, this is not any more dangerous than installing software from the Arch User Repository or NPM or any number of user-contributed package systems.

Shop smart.



Cover image from Andrew Beierle at [Free Images](https://www.freeimages.com/photographer/andrewatla-57677)