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
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>
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;
}
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;
};
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"]
}
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:
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
✅:
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)
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! :)
@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!
Merged your pr request. 👍 @joelbonetr
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.Thank you for making a contribution! 🤓
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)
@metammodern Thanks for this comment. It got me thinking.
Appreciate your feedback!
Hey @hr21don
Ti here --
I was able to find some time today, and I've implemented a few changes.
This PR mainly handles:
README.md
to the root of the project, explaining the different commands to run for development, and building the extension.www.discord.com
andwww.twitter.com
, however, this check failed since thehostname
for those sites didn't have thewww
.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 🚀
Very nice! I appreciate the contribution your making to the repo. @tiru5
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!!!
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 🚀
I liked the animation. Nice job
I found my inspiration from this little snippet found here on codepen.
Really impressive
This is interesting, also contributed and would make more meaningful addons later on.
Fun concept idea.
Thanks!
Thanks for sharing.