While setting up Quartz as described in the Quartz docs, the native way intrinsically supports the idea of separating the content from the code, by creating a soft link between the two. Weâll use a submodule to further achieve this idea.
Why submodules
There are several reasons that make you wanna try putting your /content
separately in a (private) Git repository.
- You are editing your contents in Git and you donât want to mix up the commits of
/content
with the updates of the codebase. - Your contents are private. But for some reason, you have to make the blog repository public (e.g. when you want to host on GitHub Pages for free, or when you choose to use Giscus as comment manager).
- Quartz allows you to label your posts with
draft: true
in frontmatter to keep them from showing up. But a opened-up/content
will spoiler what youâre working on.
We are working with Git Submodules and Cloudflare Pages in this tutorial. Weâd use Cloudflare Access to fortify sensitive areas of your blog.
Prerequisites
Create a submodule
Make sure youâve got your blog ready. Then create a GitHub repository for your content and replace \content
.
cd quartz
# remove the existing folder or soft link
git rm --cached ./content
# replace my HTTPS URL with yours
git submodule add --force https://github.com/felixnie/Obsidian-Draftz.git content
git submodule update --init --recursive
After each commit of the content, retrieve updates by running git submodule update --recursive --remote
.
If you decide to set your submodule repository to private, a new SSH key is necessary for Cloudflare Pages to access your submodule. The standard HTTPS submodule URL relies on interactive username/password input, which isnât possible in an automated build environment.
To change the HTTPS URL to SSH URL, you can do it either manually or via CLI.
[submodule "content"]
path = content
url = git@github.com:felixnie/Obsidian-Draftz.git
cd draftz
# edit url
git config --file=.gitmodules submodule.content.url git@github.com:felixnie/Obsidian-Draftz.git
Commit after the update.
# commit changes
git add .gitmodules
git commit -m "Switch submodule to SSH URL"
git push
Generate a SSH key
Create a new SSH key on your local machine. This will generate a pair of private and public keys, namely id_ed25519
and id_ed25519.pub
.
# save as id_ed25519
ssh-keygen -t ed25519 -C "Git deploy key for Cloudflare/GitHub Pages"
Set up GitHub deploy key
Then let the public key in id_ed25519.pub
be the deploy key of your private content repository. Go to Settings â Deploy Keys â Add deploy key and paste everything but the comments (if you have any).
Make sure âAllow write accessâ is enabled.
Deployment
Cloudflare Pages
After setting up following the guide, we shall go through some extra steps to set up the environmental variables.
Add the following 2 variables to your build environment in Cloudflare Pages:
Variables | Values |
---|---|
GIT_DEPLOY_KEY | The entire content of your private SSH key, including the BEGIN OPENSSH PRIVATE KEY  and END OPENSSH PRIVATE KEY  markers |
GIT_SSH_COMMAND | ssh -i $GIT_DEPLOY_KEY -o StrictHostKeyChecking=no |
The value of GIT_DEPLOY_KEY
is encrypted and will not get exposed in build logs. Remember to deal with private keys under trusted Internet environments.
GitHub Pages
In your repository, simply add the deploy workflow but with GIT_DEPLOY_KEY
injected. Hereâs how.
name: Deploy Quartz site to GitHub Pages
on:
push:
branches:
- v4
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for git info
submodules: recursive # mod: submodules
ssh-key: ${{ secrets.GIT_DEPLOY_KEY }} # mod: ssh key
persist-credentials: false # mod: disable HTTPS token
- uses: actions/setup-node@v4
with:
node-version: 22
- name: Install Dependencies
run: npm ci
- name: Build Quartz
run: npx quartz build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: public
deploy:
needs: build
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
Then add GIT_DEPLOY_KEY
in Settings â Secrets and variables â Actions â Repository secrets.
Whatâs next
Quartz is built to be shared, not exclusive. Itâs also not easy to completely hide a post. If youâre looking for some tweaks to make your pages more private, check Creating a Secret Garden.