How I hacked my Hashnode blog with only CSS and was able to manipulate any text on it

The most current version as of .

Hashnode gives you the ability to style your blog, if you are an Hashnode ambassador. You will get an input-field in the appearance configuration page, where you can paste custom CSS styles.

With this feature you can style your blog pretty much like you would like it – the styling goes into your hands.

But, what if you would like to change some of the texts on your blog. Like for example buttons, little badges, labels and these kind of stuff? Well, for that kind of override you would normally drop some lines of JavaScript.

With plain vanilla JavaScript you would go ahead and change the element’s textContent, value or even innerHTML. Using jQuery you end up writing something like .text('…') or .html('…').

Well, on Hashnode we can only inject CSS. Widgets are embedded as <iframe>s, so you can’t access the DOM of your blog pages with JavaScript this way.

It seems there is no option to change the contents of your Hashnode blog. But wait, CSS is not that powerless, you can’t change the content of text on a website using CSS, but what you can do is add content using ::before and ::after and you can also „remove“ texts through a variety of ways including display: none, opacity: 0, visibility: hidden just name a few.

And you know what – these methods are enough to manipulate the text contents of a website using only CSS.

So, I went ahead and inspected the DOM of my Hashnode block and tried multiple variations, to modify and hide elements with the custom CSS feature of Hashnode.

In case Hashnode didn’t changed their rules of what is allowed in the custom CSS code and what not, you can see with what I ended up by checking out my Hashnode blog’s homepage.

In case Hashnode changed their rules of custom CSS and prevents us from using CSS pseudo classes like ::before and ::after to change text contents, here is a video recording of what my page looks like on Hashnode, with the custom CSS injected.

Like you see on the screen recoding, I ended up building up an entire flow of different animations creation that unique experience you are seeing.

I published the entire source code of my Sass files as well as the compiled CSS files on GitHub. Feel free to check those out.

The key to manipulate the texts was to „hide“ the elements text content by setting their font-size to 0. Now, that the element wasn’t visible anymore, I could go ahed and and and ::after pseudo class to the given element selector and give it a content of pretty much everything I wanted.

With this technique I had the power to pretty much change anything I wanted to. For example to fake my follower count I could write the following Sass, compile it to CSS and paste it to my Hashnode appearance configuration page:

.blog-followers-count > span > strong
    font-size: 0
        font-size: 1.125rem
        content: '1,000,000'

Which would give my a follower count of 1,000,000 followers. Same goes for article statistics like views and reading time.

Here is what you would do, if you would like to fake your article reading times:

.blog-post-card-meta > a[aria-label*='min read'] > span:after
    content: 'to long to read'

And here you go for your article views:

.blog-post-card-meta > a[aria-label*='views'] > span:after
    content: 'to many views'

You got it, you can grab any selector from the dev tools and put it into your custom CSS rules to manipulate the text contents of the choose element.


In my case I was twerking these CSS hacks with a fun background – nothing seriously. That’s why I ended up using emoji a lot, because I only want to demonstrate what’s possible using just CSS, so you can still clearly see all manipulations, what you would definitely not, if I would have typed things out in a way they are displayed naturally.

When you are editing you custom styles in Hashnode you have a sidebar on she right contains some useful informations to note when applying custom CSS rules. Here is what it says about things you should not do:

I would suggest @hashnode to either disallow these kind of manipulations by including them in their dont’s list or block the usage of ::before and ::after completely from the custom CSS feature, because as you could see based on my demonstration, this feature could be abused to fake content easily.

— David Wolf