This is a Livecoding Recap β an almost-weekly post about interesting things discovered while livecoding. Usually shorter than 500 words. Often with pictures. Livecoding happens almost every Sunday at 2pm PDT on multiple channels. You should subscribe to My Youtube channel to catch me live.
One of my most pointless timesucks is imgur.com.
Maybe you don't know what that is, or think it's an image host for Reddit and never realized it's got a homepage. Imgur is bigger than Reddit, actually.
That's news from 5 years ago. π€ Am I not hip with the kids anymore?
Either way, Imgur is great. Full of fun images, crap comments, and there's always the next gif to see. Sometimes world news.
You open it up, it greets you with enticing thumbnails and before you know it, it's 20 minutes later and you're waaaaay past your break time.
I built hideimgur.com to fix that. Itβs a Chrome extension that replaces Imgur's homepage with tips for taking a healthy break. Sometimes it tells you to do push ups, sometimes to go chat with a human being. It's great.
And no more imgur addiction. Fixed me in 2 days! π
You can see the code on GitHub and watch the livecoding video π to see how it's built.
Here's the process for building and launching your Chrome extension in a nutshell. π
Create an extension
Google's official getting started tutorial is great. You should skim it whenever you get stuck.
First, you'll need to create a directory and a manifest.json
file.
{
"manifest_version": 2,
"name": "Hide imgur homepage",
"version": "1.1",
"description":
"Replace the Imgur homepage with tips for taking a healthy break. New tip every time you slack.",
"icons": {
"16": "icon16.png",
"48": "icon48.png",
"128": "icon128.png"
},
"content_scripts": [
{
"matches": ["*://imgur.com/*"],
"js": ["hide-imgur.js"],
"css": ["hide-imgur.css"],
"run_at": "document_start"
}
],
"permissions": ["tabs", "*://imgur.com/*"]
}
It's a JSON config file that tells Chrome how your extension is supposed to work. The important parts are π
manifest_version
,name
, andversion
are all required. You need those for your extension to work at all.description
is useful but not crazy important. I'm not even sure where it shows up for the user.- You need 3
icons
for various places Chrome puts them. You should make a simple image and resize it to 16x16, 48x48, and 128x128 pixels.
You've created a Chrome extension! Congratz π
Not very useful yet. I wanted mine to get permissions for imgur.com
and run content_scripts
when you open that page.
That's defined in content_scripts
and permissions
. The first tells Chrome which files to load when the URL matches imgur.com
and when it should run.
document_start
lets you run scripts before the page is loaded. Avoids a lot of content flicker.
permissions
aspecifies which permsissinos you want to ask for. The fewer you ask for the more your users will like you.
Nobody likes to see that "X asks for permission to access all your sites" notifications. Are you a keylogger?
PS: You could totally build a keylogger like this. Please don't.
Write some JavaScript
You can do a lot of things with Chrome extensions. Everything from changing the default new tab to adding window dialogs.
For Imgur hiding, we need a content script. Itβs the simplest Chrome extension to build, I think. A JavaScript file that runs in the context of a page.
The fun part is avoiding frameworks.
The DOM is fast these days and pretty easy to use. Here's a function that hides an element on the page whether it's loaded yet or not. Remember, we're running before the DOM is done loading.
// hide-imgur.js
function hideElement(query) {
let el = document.querySelector(query);
if (el) {
el.style.visibility = "hidden";
return true;
} else {
return false;
}
}
function hideAsync(query) {
const hidden = hideElement(query);
if (!hidden) {
setTimeout(function () {
hideAsync(query);
}, 100);
} else {
putUpSomeContent();
}
}
In hideElement
, we look for a DOM node. If it's found, we set its visibility
to hidden
and return true
. Otherwise, we say nothing happened.
It's important to toggle visibility instead of the usual display: none
because it avoids removing the node, just hides it. We want to avoid removing the node because if we collapse the page to zero height, Imgur's infinite scroll falls into an infinite loop and eats all our CPU.
That was fun to discover π
hideAsync
is a wrapper on top of hideElement
that waits until nodes are rendered before hiding them. Takes a query, calls hideElement
, if nothing happens it waits 100
milliseconds then tries again.
If hiding worked, it runs the function that puts healthy tips on the page.
Finally, we loop through all distracting elements of Imgur and hide them in a loop π
// hide-imgur.js
// Go through dangerouns elements and hide them
[
"#imagelist",
"#top-comments",
".sentence-sorting",
"#right-content",
"#extended-imagelist",
".next-prev",
].forEach(hideAsync);
You can find those elements with the Elements tab of your Chrome dev tools. The key is to find the topmost node that wraps all the content, but doesn't wrap too much of the content.
Bit of an art. And it's gonna break when Imgur redesigns.
The definition of fragile code π
Launch
Launching your extension takes you to one of the worst designed websites I have ever seen: The Chrome Web Store Developers Dashboard
Detailed instructions in Google's devguide
You pay a $5 fee the first time you publish, upload a zip file of your directory, add some descriptions and screenshots, and you're off to the races.
Next time you search Chrome extensions, your baby will be there.
π€
PS: It helps to make a nice landing page before you post to ProductHunt and places like that. I used carrd.co to do that.
Continue reading about Build a Chrome extension from idea to launch in an afternoon
Semantically similar articles hand-picked by GPT-4
- Livecoding recap #42: HackerNews app where people are nice
- Livecoding #35 - A New Site for reactd3js.com
- Livecoding 52: First impressions of Vue
- CodeWithSwiz: Privacy-focused embeds for YouTube, Twitter, et al
- Livecoding #27: New React Indie Bundle page almost done
Learned something new?
Read more Software Engineering Lessons from Production
I write articles with real insight into the career and skills of a modern software engineer. "Raw and honest from the heart!" as one reader described them. Fueled by lessons learned over 20 years of building production code for side-projects, small businesses, and hyper growth startups. Both successful and not.
Subscribe below π
Software Engineering Lessons from Production
Join Swizec's Newsletter and get insightful emails π on mindsets, tactics, and technical skills for your career. Real lessons from building production software. No bullshit.
"Man, love your simple writing! Yours is the only newsletter I open and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. π"
Have a burning question that you think I can answer? Hit me up on twitter and I'll do my best.
Who am I and who do I help? I'm Swizec Teller and I turn coders into engineers with "Raw and honest from the heart!" writing. No bullshit. Real insights into the career and skills of a modern software engineer.
Want to become a true senior engineer? Take ownership, have autonomy, and be a force multiplier on your team. The Senior Engineer Mindset ebook can help π swizec.com/senior-mindset. These are the shifts in mindset that unlocked my career.
Curious about Serverless and the modern backend? Check out Serverless Handbook, for frontend engineers π ServerlessHandbook.dev
Want to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz React components your whole team can understand with React for Data Visualization
Want to get my best emails on JavaScript, React, Serverless, Fullstack Web, or Indie Hacking? Check out swizec.com/collections
Did someone amazing share this letter with you? Wonderful! You can sign up for my weekly letters for software engineers on their path to greatness, here: swizec.com/blog
Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com
By the way, just in case no one has told you it yet today: I love and appreciate you for who you are β€οΈ