How I removed my LinkedIn connections in bulk
And how I had to write a custom javascript logic to do it.
NOTE: This article is quite old and the code in it might no longer work on LinkedIn. However, the principles behind it are still valid.
I opened my LinkedIn profile the other day and I realized that I had over 250 connections. Not only that but most of them were not even relevant to me. I decided to clean my list of connections all at once.
But, on LinkedIn, it is only possible to remove a single connection at once and it takes 3 clicks to get it done!
I knew I wanted to get rid of around 100 connections. Doing that by hand would take me a lot of time and a lot of clicks. So I decided to write my own custom code which would inject a couple of checkboxes and buttons to the page which would make the necessary clicks for me. Additionally, this was a great opportunity to learn to use the MutationObserver
.
This post describes what I did and how my custom code functioned.
Please note that it is your own responsibility for using any code in this post.
Injecting custom code
I did not want to spend any time making a custom Chrome extension. So I decided to use this existing extension to allow me to inject my custom code to the LinkedIn page. I like this particular extension because it offers a nice editor to write the code, too.
Data persistence
I started with handling the data for my script. The logic is very simple. The script adds a global __f
object to hold all the data. This object is then loaded from localStorage
upon initialization and saved to it before the page unloads. The code looks like this:
Sidenote: why __f
? I actually don’t know. It came to me while I was on a toilet…
This part of the code is very straightforward and does not use anything magical. The only interesting part is the use of the beforeunload
event to save the data before exiting the page. It also sets the default values if not data was stored before.
Initializing a MutationObserver
Let me first elaborate on why I chose the MutationObserver
. Well, my first idea was to simply use load
event. But, that did not work because I could not easily detect when the relevant HTML elements appear. I did not want to use some weird logic with setInterval
to keep checking for them.
MutationObserver
lets you get notified when there are any changes to the DOM. This means that I could run my own logic when the relevant elements were added to the DOM. Here’s how I registered my callback function:
Enhancing the connection cards
The next step was to add my own logic to the connection cards. There are HTML elements on the page which show the connection details. They also allow the user to perform actions with this connection.
My goal was simple — to add a checkbox somewhere to this card and handle the logic of selecting and de-selecting cards. First, I tried to remove the button and add a checkbox. But, I decided later to reuse the existing button and redefine its behavior.
This code is very straightforward. When it receives a mutation change, it checks whether it is a connection card. If it is, it calls a handler to set up custom logic for that card. This way, the code handles all the connection cards, even those that are loaded later as I scroll the page. Let’s have a look at the card handler function.
I used the names to identify the connections. The handler function first gets the name from the card. Then it changes the button text and registers custom behavior. Finally, handles style changes when the card is selected.
Now it was possible for me to select all the connections that I wanted to get rid of. And thanks to the use of MutationObserver
and localStorage
, I could even reload the page. The connections would still remain selected. Perfect!
Removing connections in bulk
What we all have been waiting for…
It was time to make the final piece of the puzzle — the ability to remove the selected connections. I started by checking the network request that is made when I manually remove a connection. It turned out that the browser made a request such as this:
DELETE
https://www.linkedin.com/voyager/api/relationships/connections/<ID>
The request contained a mysterious ID which I could not find in the DOM. So I decided that instead of making HTTP requests, the script would only click on buttons. But first, I needed to add a START REMOVING button which would start the process. I modified the observeCallback
function to this:
As you can see, the script is waiting for the connections header element to appear in the DOM. When it does, the script calls a handler function. This handler then inserts a button which triggers the start of removing. Here’s how it looks:
There’s a lot happening inside this code snippet! The first function handler is called from the MutationObserver
callback function. It attaches a large red button to the header.
When this button is clicked, it calls the startRemoving
function. This one checks whether there is anything to remove in the first place. If there is, it sets the global state and calls the keepRemoving
function. The keepRemoving
function tries to find the correct connection card for the first selected name. It does this by getting all cards and finding the one with the correct name. When it finds the correct card, it finds its dropdown button and clicks it. The rest of the functionality happens in the MutationObserver
callback function. Let’s take a look at it again:
As you can see, when the callback sees an added dropdown button, it clicks it. Then when it registers the confirmation modal, it clicks its confirm button. This all works because the LinkedIn page is inserting and removing DOM elements to show the dropdown and the modal.
Detecting removed connections
Finally, I wanted to deselect a connection once it was removed. Then I wanted to keep removing the rest of the selected connections. For that, I needed to detect when the connection card has been removed from the DOM. Let’s get back to the MutationObserver
callback function:
I had to use querySelector
instead of matches
on the removed node. This is because the callback function only gets the top removed element and not the connection card element itself. In this case, it was the li
parent element of the card.
The handler function checks whether the script is currently removing this connection. If it is, the name is removed from the list of selected connections. Then the process continues by calling startRemoving
again.
So there you have it! Running this script on the LinkedIn page allows you to bulk remove your connections. It does so by using the MutationObserver
. It allows you to toggle which connections to remove and then removes them by pressing the buttons in the DOM for you. Easy!
Here’s the final version of the script:
If you have any suggestions for the code let me know in the comments. Please note that this is not production-grade code at all! 😄
Thank you for reading this post. If you like it, make sure to give it a 👏 and follow me for more awesome goodies. Have a nice day!