I switched a couple other sites to static-hosting sites in AWS. The architecture was pretty standard, an bucket to host the assets connected to a distribution which took care of routing, SSL, and caching, and a DNS entry to point my domains to the right CloudFront distribution. Simple system diagram below:
I've been using Notion for about a year now to organize my life. It's fantastic. You should too.
Download content from Notion using the same (not-publicly-documented) API that Notion uses internally to render their app and render with (which ). An example is (a app), which was one of the first attempts at generating Notion-based static sites. The major downside of this approach is that it relies on Notion's internal API which could change (or be locked down) at any moment.
Download content from Notion using their and render it using React. This , , and are examples of this approach. They have the advantage of using , but unfortunately this API doesn't yet support all block types — it doesn't support blocks I use frequently, like , , or . Some of these systems fall back to approach 1, or else just don't display unsupported block types.
Approach 3 looked most promising to me, but I wanted to be able to do a quick, one-click site update, and ideally share that with a few trusted, non-technical people. is a free service (requires a Google account) where you can run Python code. It's typically used by data scientists for small projects. But notebooks can be shared like Google Docs! So it looked like a promising option.
Here's the system diagram I had in mind:
After some tinkering, I cooked up a Google Colab notebook with a Python script that gets the job done. Below are the steps to replicate my set up:
Create a page in Notion which will become your website root. (In my Notion, I've set up a page called "Websites," under which I have a separate page for each public Notion-driven website I've set up.)
Make the page you created in step 2 is public (Share → Share to web) and note its public URL.
Log into your AWS account.
Request an SSL certificate from AWS Certificate Manager. This can take some time, which is why we do it first.
Create an S3 bucket in AWS with the same name as the domain where you want to host the site (like).
(Optional) Create afile and upload it to your S3 bucket's root.
(Optional) Create afile with any custom CSS you want on your site (I have the following to hide the Notion top-bar) and upload it to your S3 bucket's root:
Create aconfiguration file like the one below (customize it with your own settings, remove scripts and CSS if you didn't create them in steps 6-8 above) and upload it to your S3 bucket:
Create a CloudFront Distribution in AWS which is backed by the S3 bucket from step 5. Note the CloudFront distribution's ID and ARN.
Make your CloudFront distribution redirecttraffic to and configure it to use your Amazon-issued SSL certificate from step 4.
Create an AWS IAM user with programmatic access. Note theand .
Point your domain at your CloudFront distribution.
Create a Google Colab notebook with the following code. Replace the settings at the top with your own.
Basically this Python script is
Installing all needed software and packages:
, the headless browser used to download Notion pages
, the package that turns a Notion page into static assets in a local folder
, the AWS client Python library
, the Python library that ensures assets are uploaded to S3 with correct types
Downloading the Notion page(s) and creating the static version
Uploading static assets to the S3 bucket
Invalidating the CloudFront distribution's cache, so the updated site appears immediately
One caution here: every time you run the Google Colab notebook, you're re-downloading the entire website, re-uploading it to S3, and purging the entire CloudFront cache... all of this will take longer, incur more AWS costs, and may run into rate-limits from Notion, as your site gets bigger or if you update it frequently. Running it for a pretty simple one-page site takes just over 1 minute. Running a bigger site with a couple dozen pages takes maybe 5 minutes.
But, you can use Notion as a CMS for your website.
Costs involved are
domain name registration, maybe $15/year
$0.50/month for a Hosted Zone in AWS Route53
$0.023/GB for storing assets in AWS S3 — realistically, for small site, you're unlikely to exceed free usage tier
$0.085/GB data transferred out to the Internet — realistically, for a small site, you're unlikely to exceed the free usage tier
$0.005/ CloudFront cache invalidation path (operates on all assets) after the first 1000 — again, for a small site, you're unlikely to exceed 1000
Google Colab, Loconotion, and AWS ACM certificates are all free. So for a small site, you can expect to pay around $20-$25 per year all in, which is pretty cheap!