Web Browser Extension

YouTube Regulator Extension.

profile picture of Lorenzo

Lorenzo Ramirez

an application's dashboard on two computer screens

introduction.


Personal Needs

This project was originally planned for only me to use as a very minimal browser extension. It was originally designed to remove specific buttons and sections of the site that kept me active on the site. That’s a very specific use case, and I didn’t think that it was broad enough to develop into a full application for public distribution. However, that changed when I started to research YouTube addiction.

Like most social media, YouTube is designed to steal as much as the user’s attention as possible. They even hide links to other sites behind popups and dropdowns to avoid the user leaving the site. It’s a serious issue and I don’t see it becoming regulated anytime soon (as of March 2025), so I took it upon myself to create this extension to help myself and hopefully others with this time-consuming habit. I'm pleased to introduce... Restrict the Tube!

Limitations of General Website Blockers

YouTube, as unregulated and addictive it is, is still a very valuable resource for educational research and current events. I didn’t want to take away that resource entirely. Before thinking about making a browser extension for this issue, I tried to use basic website blockers, like uBlock Origin. I found myself disabling the block whenever I wanted to use YouTube for whatever reason. That obviously defeats the purpose of the extension. Eventually, I just left the extension disabled and went about my time on YouTube uninterrupted.

I thought about why I would disable it with no issue, even though it goes against my own goals. I concluded that I was being too restricted from the site… Attempting to change from constant use to absolutely no use was too drastic of a change to realistically maintain. A new solution was required for me.

The main idea is to wean off the platform little by little, no whiplash-like changes, by perhaps restricting some elements of the site rather than in its entirety. The Limitation System is what is used to help that main idea become feasible, unlike general blockers that are more all-or-nothing solutions.

tech stack.


Vanilla Web Languages

This browser extension uses vanilla web technologies - HTML, CSS, and JavaScript - and Chrome’s extension API to do its magic within a web browser context. This project was my first real chance outside of coursework and co-op projects to utilize and develop my web dev skill set in a semi-real environment. I took my time to really learn how each technology works through many, many hours of trial and error. 😮‍💨

I became very indecisive when I was trying to figure out which coding techniques and libraries I should use to develop the features. Too many times, I developed a feature almost completely, and then realized “hmm, I don’t like this” and restarted using a different method or library. Even though I scraped a lot of my early code, I still found value in the attempts, because I learned methods of project folder structure and proper documentation.

Frontend Tech

  • logo of HTML

    HTML

  • logo of CSS

    CSS

  • logo of JavaScript

    JavaScript

  • logo of jQuery

    jQuery

  • logo of Figma

    Figma

Backend Tech

  • logo representing chrome API

    Chrome API

the process.


Project Requirements

The requirements of this extension changed quite a bit during development. Some features stayed the same from their inception, but others were too complex or too out of scope for a web browser extension. New, more interesting, features were also popping into my head almost on a daily basis during early development, so it was tough to narrow it down to handful necessary features! As the scope and main purpose were defined, a significant number of features had to be left behind. 😔

As previously mentioned, the extension needed to uniquely limit YouTube, in more ways than simply blocking the entire site. The features and requirements that made it out of the cutting room were the following:

  • Compatible w/ Chromium browsers

  • Local browser storage for user data

  • Efficient YouTube limitation system

  • Accurate watch time tracking system w/ categorical tracking

  • Restriction event scheduling system w/ interactive calendar

  • Block any website in a general sense

  • Spoiler keyword detection & obscurement

  • Intuitive user dashboard & settings pages

Constructing Database

Chrome extensions rightly restrict the use of external tools, such as libraries, code injections, and databases. They don’t even allow inline CSS stylings! So, I wasn’t able to connect an external database to save the user’s settings and statistics.

Luckily, Chrome provides a Local Storage API as a worthy substitute, so I can maintain user settings across the extension’s own pages and within a website context. To be honest, I don’t think an external database is even warranted here, because the database isn’t complex enough to go through the trouble of setting it up.

Regardless, I emulated a relational database as best as possible when designing the database and all of its accompanying functions. Even though the database API has very basic data manipulation function, I recreated a majority of them to manipulate and retrieve data within the database structure I created.

Another way Chrome protects users from malicious actors using extensions is restricting how data and code are transferred between contexts, such as websites, extension pages, and browser storage. The problem I ran into with that is that I couldn’t access the user’s limitation settings on other sites besides the extension’s own pages. However, Chrome provides another API to solve that issue: Runtime API !

With the chrome.runtime API, I can send and receive messages between different contexts. So, to access the user’s settings from non-extension web pages. The script loaded into those pages will send a message to the extension’s service worker script, which is in the context of the extension pages.

If the message is valid, the service worker retrieves the requested data from the extension’s local storage and sends it back to the web page script as a JSON response. This reliable method is also useful for more than connecting with the database, such as sending/receiving status messages between contexts.

Admittedly, the database-related functions are somewhat spaghetti code and difficult to understand, even for the person who wrote it (me 🫥). To be fair, it was my first time attempting anything like that. I’m a bit of perfectionist, so I will definitely take the time to rewrite the functions with more stability and clarity in a future update!

features.


Dashboard

a screen displaying an overview of dashboard page

Having one page that shows all the essential information to the user is such a valuable feature. The dashboard idea wasn’t in the initial plan until I attempted to design how to display watch times and the calendar to users. There was not enough information to warrant their own pages, so a dashboard with widgets was now required and a no brainer.

Watch times are visualized as a graph or a list, which can be filtered by video type or timeframe. The available video types are long form and short form, which are gathered individually when users are watching YouTube. The list of watch times can be grouped as either daily, weekly, or monthly timeframes.

The graph is more flexible with choosing timeframes; users can choose specific dates as the start and end dates, while still being able to filter by video type. I know lists and graphs aren’t the most exciting, but once someone watches YouTube for a long time, they can more easily see how much time YouTube is taking from them.

Four smaller widgets are stationed along the top row of the dashboard above the watch times widgets. Some widgets show watch statistics that I thought would be fun to know, and another widget shows any active Spoiler Groups. One pair of widgets show the users how much time they spend watching long-form videos compared to short-form videos in percentages. Another pair displays the day the user spent the most time watching YouTube and what their average watch time per day is, respectively.

Currently, the dashboard is not customizable. However, I love that kind of feature, especially to make the application my own personal experience, so I’m definitely open to implementing that in future update! 😎

YouTube Limitation System

a screen displaying youtube limitations settings page

This feature is the bread and butter of this extension; the whole reason this extension even exists. The user is given a list of 10+ limitation options that range from removing navigation buttons to disabling the infinite recommendation feed. Any number of limitations can be active at once to give the user the most freedom in how they set up their limitation experience. Other limitation options include, but not limited to:

  • Hiding navigation buttons

  • Hiding Shorts recommendations

  • Hiding search bar

  • Blocking home page

  • Blocking all pages

There are extra settings that determine when the limitation is activated. All limitations are able to be set to always active while most others can be set to follow schedules, which turns on the limitation only during restriction events. One strategy that I find the most effective to limit usage is to set specific buttons or infinite recommendations to always active, while blocking pages only during Restriction Events. Others may find different strategies more effective, but that one works the best for me.

The system fundamentally works by utilizing Mutation Observers in JavaScript. It searches for class names, IDs, tags, and more within a given parent container. If that element appears whenever the parent container changes, it applies the limitation to the element. One example of where this is needed the most is the navigation buttons in the side bar. None of the buttons are loaded into the DOM until the side bar is opened at least once, so the observers are especially useful in applying limitations on the fly.

One challenge I had while developing this system is inconsistency. Pages across YouTube are not built the same whatsoever. They use slightly different components, class names, and HTML structures for buttons and layouts. Even on the front end, the icons are not the same even though they represent the same element. Scouring the site was very tedious with that in mind. That is something I need to keep an eye on in case they decide to change a parent container or a class name somewhere within the site.

Watch Time Tracking System

a screen displaying watch times and graph on dashboard

Showing the user the amount of time they spend on the site may organically deter them from using YouTube, given they spend an exorbitant amount of time on it… This is why I decided to implement a watch time tracking system. I didn’t just want the system to track watch times in a general sense, so the system is made to distinguish and categorize videos by video type: long-form and short-form. Hopefully, their watch time insights can help them decide whether or not they spend too much time on YouTube.

The first iteration of the tracking system was simpler but much more inaccurate. It would add time whenever the user is focused on any YouTube browser tabs, and then save it to the database once the user leaves the tab. This provides 2 big issues:

  • Videos played in the background are not counted.

  • If they close the tab before their watch time is saved, all that time is lost to the void.

After researching how I can reliably track whenever a video is playing, even if the video is playing in the background, I found that YouTube conveniently updates an attribute of the play button according to the state of video playback. This proved extremely useful because all I had to do was set a Mutation Observer to the play button and check whenever that attribute changed. Boom! A reliable watch tracking system was born. 😎

Unfortunately, the play button attributes are not always 100% reliable. For example, the play button for YouTube Shorts is set to pause for the first video of the feed, even if it’s loaded already playing. After the first video, the attribute is updated accordingly for the rest of the watch session. This is a minor discrepancy, but I’ll make sure that type of bug is accounted for in a future update.

Block General Sites

a screen displaying blocking additional websites settings page

Now, I know that I kind of dogged on general website blockers earlier, but this is just a minor feature in this extension. Considering this extension is categorized as a productivity application, I thought it would be nice to have that option to block other websites in a general sense.

Users can add any website to a blocked list as long as they provide a valid URL address. When they attempt to load into a blocked site, they will be redirected to the dashboard where they will meet a popup that shows them their watch times and reminds them why the website was blocked in the first place.

Websites can be categorized by website type via a dropdown list. I included 4 common website types - Social Media, Shopping, Streaming Content, or Adult Content - to choose from, but users can choose the other option in case the given options aren’t accurate enough.

I have ideas on how I can improve the current system, because it is fairly basic. Currently, the websites are either enabled or disabled; they do not follow any restriction event. Another potential improvement is to offer options to block all websites that fall under given categories, but that could be difficult to implement. We will see what happens in future updates!

Restriction Schedules

a screen displaying scheduling calendar on dashboard

Being able to schedule recurring events to automatically limit YouTube helps users to be hands-off once they set up their restriction preferences. I owe a big thanks to the developers of the FullCalendar.io JavaScript library because their fully interactable calendar provides a very user-friendly scheduling experience. People familiar with Google Calendar or any modern calendar will feel right at home where they can set up events by clicking or dragging on the calendar UI itself.

The Scheduling System works in tandem with the Limitation System. As mentioned before, the limitation options that are set to follow schedules are activated only during those restriction events. Restrictions can be set to all day or during specific timeframes.

There are some limitations to the system that I would very much like to improve in future updates:

  • Events cannot span multiple days; a timeframe cannot cross midnight into a new day

  • Events set for different times and days at the same time are not grouped together once created

Spoiler Detections

a screen displaying a demonstration image of a spoiler detected.

What’s more annoying than being spoiled for something you’ve been looking forward to? That’s right... nothing! I’m someone who likes to watch new movies without knowing much about the plot or characters, so I found it incredibly frustrating when I’m suddenly spoiled while browsing recommendation feeds. YouTube thumbnails and titles are the main culprits that spoil things for me personally.

Using Spoiler Detections is very simple: add specific keywords to spoiler groups. When a recommendation feed loads, each active spoiler keyword is searched for within each video title and channel name. Once a keyword is found, the thumbnail is obscured (Obscured as a blur or a spoiler free image) while the video title is rewritten to say that a keyword was found and to avoid this video.

At this current time, the keywords are only searched for within video titles in a recommendation feed. It does not look for keywords within tags or descriptions that contain more context. I haven’t looked into how that can be done, but it is something I would want to add in a future update!

project status.


Public Release

Version 1.0 is officially published on the Chrome extension store for free! 🎊 The extension is not perfect, so I still have a lot to improve. 😅

I have plans to implement more features, such as Watch Modes and extra recommendation feeds that are less algorithmically based like the current system on the Home page. These features are explored in the official documentation, but I’m moving on to new projects to grow my portfolio and further progress in my full-stack development journey!

Please feel free to check out the extension yourself! You may also take a look at the project’s documentation for a more in-depth technical explanation of the project as a whole.

Thank you for reading! 😄