I’ve been using Typlog as my blogging platform for the past few years. It’s been an excellent product for many reasons — extremely low friction editing experience, easy-to-use dashboard, reliability. I have to admit that I don’t write very often, but when I do, it doesn’t give me a hard time. However, an idea has been keeping bugging me for the past few months.
Typlog and other blogging platforms, like Ghost.org (paid version), promise a user-friendly experience, but they’ve rarely used “customization” as a selling point. Typlog supports code injections, custom header/footer, custom HTML contents, etc, which are already better than many blogging platforms (some of the features need the Pro plan). However, customizing a component on the website is still very hard. For example, preview links like Notion.
Typlog has added the link preview support for some websites, like Douban and IMDB, still not as good as Notion.
Another reason that made me really think about migrating to somewhere else was that engineering a dynamic personal website isn’t really different from engineering a product. It’s a great opportunity to learn and experiment stuff. If you look at Brian Lovin’s personal website, it literally has everything you could think of.
How my website works
My personal website is an over-engineered playground where I can tinker, learn new things, test new tools, break all the rules, and just scratch that itch deep in my brain that wants to understand how the hell web software works.
It’s funny that before I moved to Typlog, I was using the self-host Ghost and now it’s become an option again. Developing a custom theme for a Ghost blog is tremendous work, not to mention adapting to the big yearly update. Many third-party packages like the S3 storage package haven’t been updated for years. It takes time to keep your instance and theme updated.
The paid service is good, however, it’s not cheap as I’m not a regular blogger, I also don’t need the subscription management feature.
Static Site Generation (SSG) is a quite enticing option as it can be very flexible in styling and other customization aspects. It’s now much easier to generate the website in an automated way, such as using GitHub Actions, as compared to the old way, doing everything locally.
This solution (Gatsby, Hugo, Hexo…) satisfies my current needs. However, if I want to add dynamic content in the future it’d be difficult for the following reasons:
- The solutions don’t include a running service, which means I’d need another service to output the dynamic content.
- Generating happens in build time, the time consumed only grows over time.
Notion is more than capable of being a CMS, and it’s free! The problem left is how to render the content to a browser, like a blog. There are quite a few cool services doing so.
Super - Build websites with Notion
Everything you need to build fast, functional websites with Notion. Custom domains, themes, password-protection, and more-no code required.
However, I don’t want to spend more than 10 bucks a month on this 😈.
Spencer first introduced his idea back in 2021, which uses Next.js as the renderer. It got my eyes.
Next.js probably is one of the coolest projects in the React community. It’s made by Vercel, which probably is one of the coolest companies out there.
Next.js gives different ways to deliver your content.
- Server-Side Rendering (SSR)
- Static Site Generation (SSG)
- Client-side Rendering (CSR)
The last one is what I want to talk about.
If you’ve ever used the SSG before, you know everything hosted on your server is rendered at build-time, meaning if you want to add or change content, you need to build again. ISR, however, doesn’t require the subsequent building. A page would be built when someone accesses the URL. Pages that have already been built can also be updated upon new requests once become expired. How cool is that?
Since it essentially is a Next.js service, it’s up to you to decide which parts are dynamic and which aren’t.
In order to render blocks from Notion, you’ve got two options.
Notion has its official API now. You can query your database, search content and many stuff through the API.
Start building with the Notion API
Connect Notion pages and databases to the tools you use every day, creating powerful workflows.
react-notion-x consists of two essential parts:
notion-client- A wrapper of the Notion private API used by their clients.
react-notion-x- A collection of React components that transform the raw data into actual pages with Notion-like styling.
Yes, it uses private APIs. The author published another package
notion-compatto make it possible to use the official API, but it has a few drawbacks (see the link).
react-notion-x/readme.md at master · NotionX/react-notion-x
A compatibility layer between the official Notion API and the unofficial Notion API fully compatible with react-notion-x backwards compatible with notion-client and the unofficial notion API The resulting recordMap is compatible with notion's unofficial API and react-notion-x.
You’d be amazed by how much react-notion-x can do out of the box. Kudos to Travis Fischer.
What you are seeing right now is the recharged blog that results from my days of work. I have to say “thank you” to Spencer because I copied a lot of things from this blog so that I could have this MVP this fast. I strongly recommend you to read these posts about his website if you are interested in the idea (promise me you will come back).
My blog uses both the official and the private API because the former one handles Collections better and the latter one handles rendering better.
geekdada • Updated Mar 7, 2023
Apart from copying things from Spencer’s website, I tried to solve the problems Spencer mentioned in his post.
Notion stores images (and other assets) on the S3 service. The image URLs you get from Notion’s API, either the private or the public, are signed. They are short-lived instead of permanent. There’s a chance that the page generated by Next.js is still valid but the URLs are expired, and the viewer gets a bunch of 400 errors.
geekdada • Updated Mar 7, 2023
Introducing the Resource Proxy (I know, I’m bad at naming). What it does is shown below.
The key used for indexing each asset is calculated based on the identifier. When the same identifier is requested, no matter what the signature is, the Resource Proxy always point to the same file in the private S3 bucket.
Unlike the Notion S3 bucket, which takes permission very seriously, we don’t need to react if the author changes the permission. Once the asset is saved, it’s there forever.
The Resource Proxy takes care of the dimension as well. It saves the image in a temporary place, probes the dimension using
, then saves the metadata to the database. The metadata makes it possible to use
nodeca • Updated Nov 26, 2023
If you have subscribed to my blog, the feed still works, just without the main content. Generating the body content in an RSS feed is not easy as Next.js only allows outputting HTML content unless you fiddle with
Advanced Features: Custom Server | Next.js
Start a Next.js app programmatically using a custom server.
Will be available soon.
I really enjoyed the process of building this website, especially when I could control almost everything however I’d like.