Best way to start a blog

Best way to start a blog

If you don't know Potion yet, then check it out! Here's my short journey on finding the perfect blogging solution and a bonus part about reverse-engineering of Potion's template.
In the past few years I’ve learned something about myself. I’m really good at starting. Blogs especially. What’s more, I’m also really good at finding excuses to stop writing. First in 2007, because formatting posts in html/css was a nightmare. Second attempt? No mutual love to Wordpress. Posting like a real nerd? Jekyll hosted on Github Pages felt like like I’m back to 2007. I even tried Medium, but no possibility to write a blog under my name made it really far from being a “personal”. I had to find a solution that checks all the points, and doesn’t give me any excuses to stop writing.

IndieHackers to the rescue!

I have compiled a list of things I need to go back to writing some time ago. Here it goes:
Medium-like inline editor
Short timespan from writing to publishing
No self-hosted solution
Easy way to send the post to proofreading
Good mobile support, so I can write wherever I want
Customizable domain
Customizable branding
I’m not very demanding as you can see. Nevertheless, the tools I’ve been finding didn’t feel like a good fit for me. With the raise of Notion things started looking promising, it checks 5 out of 7 points. Its mobile app is also one of the greatest advantages that made me move all of my technical writing there. Why? I can write without struggling with complicated navigation and mobile keyboard in my favorite place, right in the back of my house.
I took this picture while writing this post.
I took this picture while writing this post.
Back to the checklist. Alright, the 5 out of 7 is a good score, but still, I had two more excuses to make. Luckily, being a part of IndieHackers community does not only give you an access to the great resources for aspiring entrepreneurs, but is a place where you can find cool products before the world is even about to notice them. That’s how I found Potion.
notion image
Good SEO, my own domain and customizable styles. All of it built on top of an amazing Notion’s editor. Sounds like a perfect fit! In addition it’s built by Noah Bragg who’s building it in public. If you don’t follow along his journey just yet, make sure to follow him on Twitter.

There’s a catch

However cool it sounds, I found an excuse 😅 Even though you can add custom styles, there’s no easy way to add some static sections to your webpage. I wanted to include my bio, links to conference appearances, projects I work on etc. So close, yet so far…
notion image
I gave up for some time, but I kept my subscription active, because I was ready trade my branding in exchange for a publishing tool that suits the most of my needs. I made a decent-looking version of my blog and wanted to add analytics. According to guides you can do it by adding the embed script via Potion’s dashboard. “Wait, so you can add JavaScript as well? 😈” - my inner nerd asked…

Reverse-engineered template

The idea:
Using the JavaScript append an HTML and position it with CSS Grid.
The solution:
const template = `<div class="hello-world">Hello world!</div>`
document.addEventListener('load', () => {
  document.body.insertAdjacentHTML('afterbegin', template)
The outcome: 🛑 failure.
The injected HTML in fact appeared on the page, but also disappeared after a split of a second. My reaction?
notion image
Okay, jokes aside. We still need to find out what’s causing the issue. Without an access to the implementation details I could do only two things: request a feature or dig into the source code. Of course, I had to make my life more complicated trying some runtime JS libraries like PReact or JSX and so on, but ended up with pretty much the same result. Quick look at the Chrome Inspector and it was clear that these are not going to work well with Next.js that Potion’s using. Back to good ol’ vanilla JS was my final call. At least, it was clear that the app’s rendering happens after injecting my code and it overrides the DOM. I checked the source code of Next.js in a search for some emitted events that I might make use of. No luck:
notion image
Okay, I tried to not be hacky, but Potion forced me to. Not my fault. I just didn't want to spend 10 hours trying to figure out how to inject HTML into the website. Also, I was not going to give up on my branding this time. After all, I have already seen this custom element blinking on the page!
All I've learned after refreshing the website several time was that the Next.js overrides my custom HTML. Ergo, I need to find the point in time when the framework is done with rendering. Setting timeout was a stupid idea, although I've tried it as well. Another 5 minutes wasted, but it gave me an idea. Let's find the wrapper for Notion posts and run my custom script after that. This one looks good enough:
notion image
Alright, I found an anchor, now I need some dummy way of checking if it's already the member of our DOM.
The idea #2:
Using the JavaScript keep on checking if Notion's wrapper appeared on the website and then append an HTML and position it with CSS Grid.
The solution #2:
var interval;
interval = setInterval(() => {
	let notion = document.querySelector('.notion')
	if(notion != null) {
}, 100);

const template = `<div class="hello-world">Hello world!</div>`

const runApp = () => {
	document.body.insertAdjacentHTML('afterbegin', template)
The outcome: 🟢 success.
Actually, the partial success, as depending on your internet connection quality you could see the moment when the custom HTML gets appended to the website and the website was blinking a bit. To make the loading experience better I've decided to add a loader and hide it at the of runApp() function. The result was so satisfying that I've even added a timeout to see the loader for a bit longer. Well, I'm not the designer, don't blame me!

Let's wrap it up

Was it worth it? I'm not sure yet, but I made Potion to check all of my points from the requirements list. The good thing is, no more excuses! The not so obvious benefit is that I support the other IndieHacker, which I think is a nice thing to do in the community.
Btw - feel free to use this solution and experiment with your templates! DM me on Twitter if you need any help, have better idea to solve it, or just want to share your results.