Notion as Blog Post Creator/Provider
I’ve recently re-built the Trinity website and got to the point where the website required a blog section. It needed to be accessible to other employees in the company as well as being able to handle asynchronous updates and not be tedious to implement.
Â
Exploring Alternatives to MDX
Initially when looking into blog post creation with NextJs, there is a lot of information that suggests using and supporting MDX. At first look, sure! this seems about right? Full control over writing presentation and support for code blocks. But… doing it this way means I have to support the knowledge of MDX internally and have to likely teach it to whoever wants to be able to contribute to blogs. Absolutely not something I want to deal with!
Â
The Role of Authentication
Another issue that manages to find it’s way into the equation with MDX is authentication, I can commit to MDX but then I have to wrap my own auth around posting and editing blog posts. Sure, I can probably host the files on Supabase and use their auth systems, easy enough! I’ve done that before. But then I have to create login screens and roles and think about how content editing would work and again… not something I really want to do.
Â
Discovering Notion’s Potential
So what comes to mind? Notion… We use Notion internally for odd bits of documentation and it works great as a writing tool, there must be a way to leverage this right? First method I tried to use was exporting Notion pages as HTML and storing them in my public directory and just embedding them as I saw fit. This worked, but I find myself loosing the live feel of Notion. Not really a point in using this method if it just generates static pages that can’t be updated post fact.
Â
So I kept digging around and found react-notion-x a great package that does lightweight and fast rendering of Notion pages in React. Perfect! This is what I ended up using and it works just as expected. I get to subvert my previous issues of auth and MDX just piggy backing on Notion, only users that are in my team can access the pages and they can happily edit and create Notion pages asynchronously and they update live in realtime.
Â
Thinking about Data Storage
At first I decided I would statically store my data in a JavaScript file as an array of JSON objects as the following:
Moving forward I decided against that this was too static and it also had repercussions of increasing my JS bundle size, so with that; decided to move this surrounding data into Supabase as the following data structure and moving images into their own buckets and just supplying links instead of StaticImageData.
Â
Stories:
id | title | metaDataTitle | description | imgUrl | imgAlt | date | keywords | tags | author |
string | string | string | string | string | string | timestamp | string[] | string[] | id |
Authors:
id | name | imgUrl | position |
number | string | string | string |
Â
Combing NextJS & Notion
Now that we have stored our blog data in Supabase I can use the supbase-js client to do my data fetching inside a server rendered page. This data then gets passed down to the NotionPage which is client rendered. I rather like the workflow here as I have all the capabilities of the new app dir loading.tsx and I have all my cached data in hand to do SEO.
Â
What using server rendered pages gives me here is the ability to use the new async loading.tsx skeleton, as we are using the new new app dir sync function components we can show a minimal loading screen while we are fetching our content.
Â
You may assume this would impact SEO because Notion would need to index the content, right? Well, as it turns out, you can confidently disable indexing in Notion. This will help avoid the issue of low-ranking content due to duplication.
What is also rather lovely, if you look in the code block above. You will see that on the server we have all the blog data in hand which we can provide to create JSON-LD data along side standard generatedMetaData.
Â
All in all, the more I repeat this pattern, the more I like it!
Â
FAST! 🏎️
I wanted to come back here and show off some speed improvements I’ve done on my personal site I’ll add these across the board eventually.
But what I tried while just messing around was using the pre-fetch tag to see if I could try insta load my articles, and would ya guess it is now pretty much instant.
You can see text content is pretty much instant and we have some wait for notion image content to load, but in comparison to above we totally skip the loading skeletion.