DEV Community ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป

Cover image for Coding an extension that blocks Social Media Websites with HTML, CSS and JS.
Helitha Rupasinghe
Helitha Rupasinghe

Posted on • Updated on

Coding an extension that blocks Social Media Websites with HTML, CSS and JS.

In this post, I will show you how you can create a Google Chrome extension that will block social media websites like Twitter: Facebook, Instagram, LinkedIn, WhatsApp, Reddit etc. Add this extension into your browser and achieve better productivity.

Creating the project

Go ahead and initialise our new project using the CodePen playground or setup your own project on Visual Studio Code with the following file structure under your src folder.

Social Media Blocks
  |- assets
    |- css
      |- styles.css 
    |- images
      |- logo16.png
      |- logo128.png
  |- /src
    |- popup.html
    |- popup.js
    |- manifest.json
Enter fullscreen mode Exit fullscreen mode

Part 1: modifying our HTML file.

Before we get started let's replace our index.html file with the following boilerplate code:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <link rel="stylesheet" href="assets/css/styles.css">
  <title>Social Media Blocks</title>

</head>

<body>
    <div class="modal-header">
        <h1 class="logo">
            <img src="./assets/images/logo128.png" alt="Social Media Blocks" class="logo-icon">Social Media Blocks <span class="version">(1.0.0)</span>
        </h1>
    </div>
    <div class="modal-content">
        <p> Early Access To Social Media Blocks !</p>
    </div>
    <div class="modal-icons">
        <div class="container">
            <h3>How to access:</h3>
            <ul>
            <li>Clone this repo on <span><a href="https://github.com/JavascriptDon/Social-Media-Blocks-Extension" target="_blank">github</a></span>.</li>
            <li>Go in to Google Chrome Extensions and turn Developer Mode on.</li>
            <li>Click on Load Unpacked.</li>
            <li>Select folder which contains content of this repos.</li>
            <li>Click the switch button to turn extension on and it should work.</li>
            </ul>
        </div>
    </div>
    <div id="modal-footer">
        <a href="https://github.com/JavascriptDon/Social-Media-Blocks-Extension" target="_blank"><p>MIT ยฉ HR</p></a>
    </div>
</body>

<script src="popup.js"></script>
</html>
Enter fullscreen mode Exit fullscreen mode

Note ๐Ÿ’ก - Remember that the number next to logo16.svg represents a 16x16 dimension and so on.

Part 2: modifying our CSS file.

Next step is to add the following styles to our style.css file.

/*Just here for aesthetics!*/
html,body{
    font-family: 'Poppins', sans-serif;
    font-size: 16px;
    margin: 0px;
    min-height: 180px;
    padding: 0;
    width: 384px;
}

h1{
    font-family: "Open Sans", sans-serif;
    font-size: 22px;
    font-weight: 400;
    margin: 0;
    color: #000;
    text-align: center;
}

h3{
    font-size: 15px;
}

img{
    width: 30px;
}

p{
    text-align: center;
}

.modal-header{
    align-items: center;
    border-bottom: 0.5px solid #231955;
}

.modal-content{
    padding: 0 22px;
}
.modal-icons{
    border-top: 0.5px solid #231955;
    height: 50px;
    width: 100%;
}

.logo{
    padding: 16px;
}

.logo-icon{
    vertical-align: text-bottom;
    margin-right: 12px;
}

.version{
    color: #444;
    font-size: 18px;
}

a:link, a:visited{
    color: #231955;
    outline: 0;
    text-decoration: none;
}


.container{
    display: block;
    justify-content: space-between;
    padding: 10px 22px;
}

.container a{
    color: #3330E4;
}

#modal-footer{
    background-color: rgba(0,0,0,0.6);
    font-size: 15px;
    font-weight: bold;
    text-align: center;
    margin-top: 180px;
  }

  #modal-footer a{
    color: #ffffff;
  }
Enter fullscreen mode Exit fullscreen mode

Part 3: modifying our JS file.

Go to our JS file and edit the popup.js file with the following:

const generateHTML = (pageName) => {
    return `<div id="clouds">
    <div class="cloud x1"></div>
    <div class="cloud x1_5"></div>
    <div class="cloud x2"></div>
    <div class="cloud x3"></div>
    <div class="cloud x4"></div>
    <div class="cloud x5"></div>
  </div>
  <div class="text">
    <h1>404</h1>
    <hr>
    <div class='_1'>GET BACK TO WORK</div>
    <div class='_2'>STUDYING > ${pageName}</div>
  </div>

  <div class="astronaut">
    <img src="https://images.vexels.com/media/users/3/152639/isolated/preview/506b575739e90613428cdb399175e2c8-space-astronaut-cartoon-by-vexels.png" alt="" class="src">
  </div>
  `;
  };

  const generateSTYLING = () => {
    return `<style>
     body {
      margin: 0;
      padding: 0;
      font-family: "Tomorrow", sans-serif;
      height: 100vh;
      background-image: linear-gradient(
        to top,
        #2e1753,
        #1f1746,
        #131537,
        #0d1028,
        #050819
      );
      display: flex;
      justify-content: center;
      align-items: center;
      overflow: hidden;
    }
    .text {
      position: absolute;
      top: 10%;
      color: #fff;
      text-align: center;
    }
    h1 {
      font-size: 20vw;
      line-height: 1;
      margin: 0;
      letter-spacing: 0.2em;
      margin-bottom: 50px;
      color: #fff;
      text-shadow: 7px 7px 20px #00000026;
    }
    ._1 {
      text-align: center;
      display: block;
      position: relative;
      letter-spacing: 12px;
      font-size: 4em;
      line-height: 80%;
      margin-top: 20px;
    }
    ._2 {
      text-align: center;
      display: block;
      position: relative;
      font-size: 20px;
      margin-top: 60px;
    }
    .astronaut img{
      width:100px;
      position:absolute;
      top:55%;
      animation:astronautFly 6s infinite linear;
    }
    @keyframes astronautFly{
      0%{
        left:-100px;
      }
      25%{
        top:50%;
        transform:rotate(30deg);
      }
      50%{
        transform:rotate(45deg);
        top:55%;
      }
      75%{
        top:60%;
        transform:rotate(30deg);
      }
      100%{
        left:110%;
        transform:rotate(45deg);
      }
    }    
    .cloud {
      width: 350px;
      height: 120px;

      background: #fff;
      background: linear-gradient(top, #fff 100%);
      background: -webkit-linear-gradient(top, #fff 100%);
      background: -moz-linear-gradient(top, #fff 100%);
      background: -ms-linear-gradient(top, #fff 100%);
      background: -o-linear-gradient(top, #fff 100%);

      border-radius: 100px;
      -webkit-border-radius: 100px;
      -moz-border-radius: 100px;

      position: absolute;
      margin: 120px auto 20px;
      z-index: -1;
      transition: ease 1s;
    }

    .cloud:after,
    .cloud:before {
      content: "";
      position: absolute;
      background: #fff;
      z-index: -1;
    }

    .cloud:after {
      width: 100px;
      height: 100px;
      top: -50px;
      left: 50px;

      border-radius: 100px;
      -webkit-border-radius: 100px;
      -moz-border-radius: 100px;
    }

    .cloud:before {
      width: 180px;
      height: 180px;
      top: -90px;
      right: 50px;

      border-radius: 200px;
      -webkit-border-radius: 200px;
      -moz-border-radius: 200px;
    }

    .x1 {
      top: -50px;
      left: 100px;
      -webkit-transform: scale(0.3);
      -moz-transform: scale(0.3);
      transform: scale(0.3);
      opacity: 0.9;
      -webkit-animation: moveclouds 15s linear infinite;
      -moz-animation: moveclouds 15s linear infinite;
      -o-animation: moveclouds 15s linear infinite;
    }

    .x1_5 {
      top: -80px;
      left: 250px;
      -webkit-transform: scale(0.3);
      -moz-transform: scale(0.3);
      transform: scale(0.3);
      -webkit-animation: moveclouds 17s linear infinite;
      -moz-animation: moveclouds 17s linear infinite;
      -o-animation: moveclouds 17s linear infinite;
    }

    .x2 {
      left: 250px;
      top: 30px;
      -webkit-transform: scale(0.6);
      -moz-transform: scale(0.6);
      transform: scale(0.6);
      opacity: 0.6;
      -webkit-animation: moveclouds 25s linear infinite;
      -moz-animation: moveclouds 25s linear infinite;
      -o-animation: moveclouds 25s linear infinite;
    }

    .x3 {
      left: 250px;
      bottom: -70px;

      -webkit-transform: scale(0.6);
      -moz-transform: scale(0.6);
      transform: scale(0.6);
      opacity: 0.8;

      -webkit-animation: moveclouds 25s linear infinite;
      -moz-animation: moveclouds 25s linear infinite;
      -o-animation: moveclouds 25s linear infinite;
    }

    .x4 {
      left: 470px;
      botttom: 20px;

      -webkit-transform: scale(0.75);
      -moz-transform: scale(0.75);
      transform: scale(0.75);
      opacity: 0.75;

      -webkit-animation: moveclouds 18s linear infinite;
      -moz-animation: moveclouds 18s linear infinite;
      -o-animation: moveclouds 18s linear infinite;
    }

    .x5 {
      left: 200px;
      top: 300px;

      -webkit-transform: scale(0.5);
      -moz-transform: scale(0.5);
      transform: scale(0.5);
      opacity: 0.8;

      -webkit-animation: moveclouds 20s linear infinite;
      -moz-animation: moveclouds 20s linear infinite;
      -o-animation: moveclouds 20s linear infinite;
    }

    @-webkit-keyframes moveclouds {
      0% {
        margin-left: 1000px;
      }
      100% {
        margin-left: -1000px;
      }
    }
    @-moz-keyframes moveclouds {
      0% {
        margin-left: 1000px;
      }
      100% {
        margin-left: -1000px;
      }
    }
    @-o-keyframes moveclouds {
      0% {
        margin-left: 1000px;
      }
      100% {
        margin-left: -1000px;
      }
    }  
     </style>`;
  };

  switch (window.location.hostname){
    case "www.youtube.com":
        document.head.innerHTML = generateSTYLING();
        document.body.innerHTML = generateHTML('YOUTUBE');
        break;
    case "www.facebook.com":
        document.head.innerHTML = generateSTYLING();
        document.body.innerHTML = generateHTML('FACEBOOK');  
        break;
    case "www.netflix.com":
        document.head.innerHTML = generateSTYLING();
        document.body.innerHTML = generateHTML('NETFLIX'); 
        break;
    case "www.tiktok.com":
        document.head.innerHTML = generateSTYLING();
        document.body.innerHTML = generateHTML('TIKTOK');
        break;
    case "www.discord.com":
        document.head.innerHTML = generateSTYLING();
        document.body.innerHTML = generateHTML('DISCORD');
        break;
    case "www.instagram.com":
        document.head.innerHTML = generateSTYLING();
        document.body.innerHTML = generateHTML('INSTAGRAM');
        break;
    case "web.whatsapp.com":
        document.head.innerHTML = generateSTYLING();
        document.body.innerHTML = generateHTML('WHATSAPP');
        break;
    case "www.linkedin.com":
        document.head.innerHTML = generateSTYLING();
        document.body.innerHTML = generateHTML('LINKEDIN');
        break;
    case "www.twitter.com":
        document.head.innerHTML = generateSTYLING();
        document.body.innerHTML = generateHTML('TWITTER');
        break;
    case "www.reddit.com":
        document.head.innerHTML = generateSTYLING();
        document.body.innerHTML = generateHTML('REDDIT');
        break; 
  };
Enter fullscreen mode Exit fullscreen mode

Part 4: modifying our Manifest.Json file.

The manifest is a JSON file that contains all the meta information about our extension. Next step is to add the following lines of code and complete our Manifest.JSON file.

{
    "manifest_version": 3,
    "name": "Social Media Blocks",
    "description": "Developers don't talk much. Their code does all the talking. So here's a google chrome extension for developers that want to block big social media websites like Twitter: Facebook, Instagram, LinkedIn, WhatsApp, Reddit etc. Add this extension into your browser and achieve better productivity.",
    "version" : "1.0.0",
    "icons" : {"128": "./assets/images/logo128.png"},
    "action": {
        "default_icon": "./assets/images/logo16.png",
        "default_popup": "./popup.html"
    },
    "content_scripts": [
        {
          "matches": ["<all_urls>"],
          "js": ["popup.js"]
        }
      ],
    "permissions": ["activeTab"]
}
Enter fullscreen mode Exit fullscreen mode

Note ๐Ÿ’ก - Remember to check the chrome developer docs as manifest_version 3 is the latest version.

Deployment

Finally, we can load our extension in chrome developer mode like so:

Socialblocks.gif

Note ๐Ÿ’ก - Remember to click on the load unpacked button and then choose your extensions route folder path.

You should now see this on WWW.YOUTUBE.COMโœ…:

Socialblocks.gif

Recap

If you followed along then you should have completed the project and finished off your google chrome extension.

The complete source code of this project can be found on Github.

Top comments (20)

Collapse
joelbonetr profile image
JoelBonetR

That's nice as initial concept! ๐Ÿ˜

I see you're looking for contributors, if I don't forget about it (can't promise) I'll add some PRs for useful features I mind during my vacations.

Have a great weekend! :)

Collapse
joelbonetr profile image
JoelBonetR • Edited on

@helitha nevermind, already did a PR, check it out.

Now it also checks for embedded content of those blocked sites inside other websites.

Sorry for the formatting thingy, prettier took care of it nicely ๐Ÿ˜

Hope it suits you, cheers!

Collapse
hr21don profile image
Helitha Rupasinghe Author

Merged your pr request. ๐Ÿ‘ @joelbonetr

Thread Thread
joelbonetr profile image
JoelBonetR • Edited on

Np, it was fun ๐Ÿ˜‚ i wanted to toy a bit with Chrome extensions for a while so it was a good opportunity.

Btw I've first tried to set different files instead getting everything inside the main JS, it was breaking in errors because it doesn't consider it as module so I couldn't use import statements. Despite this, I'm pretty sure it should be a way to workaround that. Didn't have more time to make some tests, thought.

Collapse
hr21don profile image
Helitha Rupasinghe Author

Thank you for making a contribution! ๐Ÿค“

Collapse
tiru5 profile image
Tyrus Malmstrรถm

Hey @hr21don

Ti here --

I was able to find some time today, and I've implemented a few changes.
This PR mainly handles:

  • The addition of a build tool, I chose to use Vite since it's really awesome and blazing fast!
    • I have created and added a README.md to the root of the project, explaining the different commands to run for development, and building the extension.
    • This also adds the ability for utilizing ES6 modules, HMR, and much more.
  • Necessary code restructure and configuration needed in order to utilize Vite.
  • Fixed a bug specifically with these two hostnames:
    • discord
    • twitter
      • in the code prior -- we were checking for www.discord.com and www.twitter.com, however, this check failed since the hostname for those sites didn't have the www.

And that is pretty much it for now. Later, I'm going to work on a few feature ideas I have in mind!

Warmest regards,
Tyrus Malmstrom ๐Ÿš€

Collapse
hr21don profile image
Helitha Rupasinghe Author

Very nice! I appreciate the contribution your making to the repo. @tiru5

Collapse
metammodern profile image
Bunyamin Shabanov

Found your article through google recommendations. The code, idea and implementation is really nice, however I'd also point out that if you're having such trouble like distracting from work to social media then blocking websites will not help much. When your brains seeks for dopamine it'll do whatever it can to gain it, like opening another browser, disabling extension or using mobile phone. So as one single solution to addiction it definitely won't work, but it may work in complex with other stuff, like having more controlled and planned rest and getting more outdoor activity. Anyway, if someone has such problem find a local therapist or contact your HR, they usually know how to solve such issues)
(The article is good by the way, just enable syntax highlighting)

Collapse
hr21don profile image
Helitha Rupasinghe Author

Appreciate your feedback!

Collapse
lukeshiru profile image
Luke Shiru

Just a heads up that you can add highlighting to the code blocks if you'd like. Just change:

code block with no colors example

... to specify the language:

code block with colors example

More details in our editor guide!

Collapse
vbarzana profile image
Victor A. Barzana

Lol, I use youtube for learning too hahaha, but maybe we could block anything that is not tech related using some Google Vision to determine the labels? or maybe if it contains some specific words in the description we let it pass :) Well done, I was thinking of doing something similar to reduce distraction!!!

Collapse
tiru5 profile image
Tyrus Malmstrรถm

Awesome concept for a Chrome extension, and well executed! ๐Ÿ˜ƒ

I really like the updated animation you implemented, looks really clean and fluid.

I'd also love to contribute to this project -- when I have some free time, I'm going to implement a few features / thoughts I have and if all looks good, submit a PR.

Thanks for sharing, greatly appreciate it.

Onwards and upwards ๐Ÿš€

Collapse
lucidsamuel profile image
Samuel Akinosho

This is interesting, also contributed and would make more meaningful addons later on.

Collapse
jacksonkasi profile image
Jackson Kasi

Really impressive

Collapse
fegroders profile image
Fernando Groders

I liked the animation. Nice job

Collapse
hr21don profile image
Helitha Rupasinghe Author

I found my inspiration from this little snippet found here on codepen.

Collapse
andrewbaisden profile image
Andrew Baisden

Fun concept idea.

Collapse
hr21don profile image
Helitha Rupasinghe Author

Thanks!

Collapse
manojtr profile image
Manoj VR

Thanks for sharing.

Collapse
drawdethepotato profile image
Drawde

Thanks!!

I'm going to create a free adult site blocker, so anyone can install it!!!!!

๐ŸŒš Friends don't let friends browse without dark mode.

Sorry, it's true.