Open source this blog — Notionic

Apr 29, 2022
Based on Nobelium, it adds sidebar outline, theme switching, language switching, native commenting, contact form, etc. It also supports subpage rendering and integrates share page into the site.
This article is translated using Notion AI.
Notionic is a real-time updated static blog, synchronizing changes to Notion pages without rebuilding the deployment.
Notionic is a derivative version of Nobelium, which uses Next.js's Incremental Static Regeneration (ISR) feature to render static pages in real time. It supports deployments to services such as Vercel, Netlify,, but not to services such as Cloudflare Pages and Github Pages.

Features already implemented:
Real-time incremental rendering
Article outline
Theme switching
Multi-language switching
Page loading and transition animations
Support for sub-pages (block page)
Support for external database pages (any public page under a specified space can be rendered)
SEO and Open Graph optimization
Weekly page
Comment section that fits the website style
Contact form
Telegram notification integration
Support for pages

You can find all the code for this site in the following Github repository:

Quick Deployment

  1. Copy the Notionic Template to your space and share it with everyone.
  1. Fork this project to your Github account.
      • Replace the resources in the /public directory with your own icons, logos, etc.
  1. Deploy your project on Vercel and set the following environment variables:
      • NOTION_SPACES_ID (Required), Your Notion space ID, please refer to the Subpage Parsing section below for details.
      • TELEGRAM_TOKEN (Optional), New comments and contact form notifications will be sent to Telegram.
  1. Wait a moment and it will be deployed.
If you have any questions, click here to contact me quickly.


You can insert a /toc in the Notionic editor to display the table of contents.


This feature does not use any other dependency library, and only implements this feature with the native i18n support of Next.js and next/router. If you want to add or modify the language or copy of the website, just open lib/lang.js and modify the content.
All the text content of the entire site has been "refined" to this lib/lang.js file, which means you can modify the text content of every part of the site in this file.
If you need to add a new language, first add your language and its corresponding translation in lang.js following the format, then modify the i18n configuration in next.config.js.
As shown below, please make sure that the abbreviations of the languages in the two files are consistent, for example:
  • If you add a new language, named zh-HK in lang.js
// lib/lang.js export const lang = { zh: { ... }, zh-HK: { ... }, en: { ... }, ja: { ... }, es: { ... } }
  • So in next.config.js you also need to configure the same language abbreviation zh-HK for it to take effect.
// next.config.js i18n: { locales: ['en', 'zh', 'zh-HK', 'ja', 'es'], // If you want to change the default language, // you can change the defaultLocale configuration. defaultLocale: 'zh', localeDetection: false },
The current language switching button only supports switching between two languages. To modify the language to switch, you can edit the expression in components/LangSwitcher.js, currently it is switching between Chinese and English.
<Link locale={locale === 'en' ? 'zh' : 'en'} passHref href={asPath}>

Subpage and External Page Parsing

Subpage parsing is enabled by default. For security reasons, you should set the NOTION_SPACES_ID environment variable, otherwise anyone can parse other people's Notion pages through your domain.
You can find your NOTION_SPACES_ID by following these steps:
  • After successful deployment on Vercel or elsewhere, open your site and click on any article.
  • Right-click and select "View Page Source", search for the keyword space_id in the source page, the first one you find is your NOTION_SPACES_ID.
  • Fill in the environment variable in the Vercel project settings with NOTION_SPACES_ID and its corresponding value.
In this way, the site can only parse pages in the Notion space you specify, and others cannot parse any Notion page through your site.
This is a sample subpage


Nobelium itself supports two types of articles, Post and Page, corresponding to blog articles and blog pages. I added a type Newsletter, which is similar to Post, but will not appear in the blog article list on the homepage.
When you create a page in your own Notion database, select Newsletter (if there is none, create one in the database) for Type, the page will not appear in the blog article list, but will be displayed on the Newsletter page.

Comment Section

Since the comment systems supported by Nobelium seem to be not very good or not matching the website theme, I decided to make one myself so that the comment section looks more consistent with the website style.
The comment content is stored in Supabase, and the free version is enough. To configure this comment section, you need to register a Supabase account, then create a database, and then create a table called comments with the following table structure:
id - int8 name - text email - text postURL - text comment - text created_at - timestamp show - boolean
Table Structure ReferenceTable Structure Reference
Table Structure Reference
Then, copy the anon key and URL from the settings --> api page in the database, paste them into the two lines of supaCommentsConfig in the blog.config.js file, and modify the provider to supacomments.
It's anon key, not secret, don't copy it wrong.It's anon key, not secret, don't copy it wrong.
It's anon key, not secret, don't copy it wrong.
provider: 'supacomments', // leave it empty if you don't need any comment plugin supaCommentsConfig: { supabaseUrl: '', // The url of your Supabase instance supabaseAnonKey: '', // The anonymous key of your Supabase instance },
The comment section is now configured. It is worth mentioning that if you configure the TELEGRAM_TOKEN (refer to the contact form below), you will also receive a notification when someone posts a comment.
The code of the comment section has not been open sourced yet because some details have not been sorted out, but it does not affect the use. The packaged code is placed in the public/comment directory, which currently supports both Chinese and English languages.>

Updated on November 22, 2022
I found that the Supabase database now requires RLS (row-level security) to be enabled, as shown in the following image:
Row-level security configuration diagram, add two policies: View Only and Insert DataRow-level security configuration diagram, add two policies: View Only and Insert Data
Row-level security configuration diagram, add two policies: View Only and Insert Data
Row-level security configuration example, adding two policies: only allow viewing and inserting data

If you get the message "data-url configuration error", please check the link item in your blog.config.js file. The comment section will only be displayed when the domain name accessed by the browser is the same as the domain name in the link.

Contact Form

The contact form will send the submitted content to Telegram.
To configure this form, you need to create a Telegram bot first. Then interact with the @BotFather bot to get your bot's API token.
Just like the NOTION_PAGE_ID environment variable added when deploying Nobelium, you need to add a variable in the Vercel backend, named TELEGRAM_TOKEN, with the value of the API token you applied for.
Finally, modify the telegramChatId item in blog.config.js to your chat id (you can ask the Telegram bot @chatIDrobot), and your contact form will be configured.
Remember to interact with the bot you created, send it a /start, otherwise the bot won't be able to send you messages. Sharing Page

Finally, support for was added, which can generate a page list in real time and proxy the sharing page. You can click the Notes in the navigation bar to see the effect. is also a software I like to use, and the sharing page of is very good. As early as last year, I wrote a Cloudflare Worker script to customize the domain name of sharing page. Later, I found that Next.js also supports a certain degree of rewrite, which can achieve similar functions of Cloudflare Worker, so I integrated into this blog.
Here is an example of the configuration page, you can copy it to your space, then modify it (you can refer to my this article for how to modify it), and then paste the link of your configuration page to craftConfigShareUrl in blog.config.js, the website will automatically generate the note page.
If the format of your configuration page is incorrect, there will be a line of words at the bottom of the generated note page to remind you. Check the format of the content in the craftConfigShareUrl page yourself.
If you don't like this feature, you just need to delete the pages/notes.js file and you won't be able to see this page anymore.

Finally, here is a version without the Notion related code, only keeping the related functions of I also open sourced it for people who need it.

Extension 1: Custom Logo

My site logo is in svg format, and many of them are written directly into the code. So modifying it may be a bit troublesome, follow the steps to modify it, if there is any problem you can private message me.
Icon for website tab
Replace all the favicon icon files in the public folder with your own.
Logo in the top left corner
You can modify it in Logo.js.
Logo on the right side of the Home page and Loading page
In the components/Hero/ folder, I have two types of Avatar examples, one called NotionAvatar.js and the other called Avatar.js. You can see the difference between them on these two websites:
Edit Avatar

Finally, refer to the following sub-pages for the modification method of the Loading icon:
Modify Loading Icon

Extension 2: Open Graph Generator

Because I couldn't find a Chinese font-friendly, small-sized and high-performance og generator, I made a small tool to generate og pictures for my website. The source code is here:
Notion's default og address is this one, if you don't need to customize more details, just use the default service address.

Extension 3: Image Link Failure

Because of the 48-hour expiration limit of Notion's external link images, after 48 hours of building the site, images from Notion will not be loaded successfully. At this time, trigger a build again to refresh the image link.
Taking deployment on Vercel as an example, in the Settings > Git settings page of the corresponding project in the Vercel management background, create a deploy hook:
notion imagenotion image
Create a directory structure .github/workflows in the code repository and create a file called cron.yaml inside, the final structure is as shown in the following picture:
notion imagenotion image
name: auto-update-cron on: schedule: - cron: '0 0 * * *' jobs: build: name: Trigger Site Rebuild runs-on: ubuntu-latest steps: - name: Call Vercel Hook run: curl -X POST ""
The code of the file is as above, change the url in the configuration to the deploy hook address you just created. After setting it up, Github will notify Vercel to rebuild the site at 0 o'clock every day, so your photos won't expire.
对于本文内容有任何疑问, 可与我联系.