A beautiful, Hugo Lanyon-inspired theme for Quartz v4 that brings a clean, focused reading experience to your digital garden.
- Fixed right sidebar with Hugo Lanyon's signature blue (
#234bc2) styling - Narrow content column (38-42rem) for optimal reading comfort
- Left-aligned content with empty space flowing to the right, just like Hugo
- Enhanced typography with 16px base font, bolder headings, and generous spacing
-
SidebarNav component - A sleek navigation panel in the right sidebar with:
- Home button with theme-aware styling
- Customizable section links
- Integrated search
- Posts link
- Dark mode toggle
- Copyright notice
-
Mobile-first header - On mobile devices, you get a fixed header bar with:
- Site title
- Dark mode toggle
- Search icon
- Hamburger menu that reveals a slide-down navigation panel with backdrop blur
The PostsListWithFilter component transforms your home and posts pages into a dynamic, filterable blog:
- Tag filter bar - Click tags to instantly filter posts (no page reload!)
- Pagination - Navigate through posts with Previous/Next buttons
- Multiple post sources - Pull posts from multiple folders (e.g.,
posts/andquestions/) - Configurable tags - Define a curated list of filter tags in your config
- Optional "About" section - Show introductory content above your posts list
Click internal links to open a slide-out preview panel instead of navigating away. Perfect for exploring connections in your digital garden without losing your place.
- Desktop: Three-column layout with TOC on the left, content in center, navigation on right
- Tablet: Two-column layout with content and navigation
- Mobile: Single-column with fixed header, hidden sidebars, and full-width content
git clone https://github.com/remyjkim/quartz-remsleep.git my-garden
cd my-garden
npm installEdit quartz.config.ts:
const config: QuartzConfig = {
configuration: {
pageTitle: "My Digital Garden",
baseUrl: "yourdomain.com",
// Optional: Define tags for the filter bar
filterTags: ["thoughts", "projects", "notes", "learning"],
// Optional: Show/hide tags on post items
showPostTags: true,
// ... other settings
},
}Edit quartz.layout.ts to configure your sidebar sections:
Component.SidebarNav({
sections: [
{ title: "About", slug: "about" },
{ title: "Projects", slug: "projects" },
{ title: "Notes", slug: "notes" },
],
postsLink: { title: "Blog", slug: "posts" },
showHome: true,
showDarkmode: true,
showCopyright: true,
// Optional: Add GitHub link
showGithub: true,
githubUrl: "https://github.com/yourusername",
})content/
├── index.md # Home page
├── posts/ # Blog posts
│ ├── index.md # Posts listing page
│ └── my-first-post/
│ └── index.md
├── about/
│ └── index.md
└── projects/
└── index.md
# Development with hot reload
npx quartz build --serve
# Production build
npx quartz build| Option | Type | Description |
|---|---|---|
filterTags |
string[] |
Tags to show in the filter bar. If not set, auto-generates from posts. |
showPostTags |
boolean |
Whether to display tags on each post item in lists. Default: true |
Configure in quartz/plugins/emitters/contentPage.tsx:
| Option | Type | Default | Description |
|---|---|---|---|
targetSlugs |
string[] |
["index", "posts/index"] |
Pages where the component renders |
showAboutSection |
boolean |
false |
Show intro content above posts |
postsPerPage |
number |
10 |
Posts per page |
showPagination |
boolean |
true |
Show pagination controls |
postsPrefixes |
string[] |
["posts/"] |
Folder prefixes to include as posts |
| Option | Type | Description |
|---|---|---|
sections |
{title, slug}[] |
Navigation links |
postsLink |
{title, slug} |
Posts section link |
showHome |
boolean |
Show home button |
showGithub |
boolean |
Show GitHub link |
githubUrl |
string |
GitHub profile URL |
showCopyright |
boolean |
Show copyright notice |
showDarkmode |
boolean |
Show theme toggle |
showReaderMode |
boolean |
Show reader mode toggle |
homeTitle |
string |
Custom home button text (defaults to pageTitle) |
Use number prefixes for ordering (they're stripped from URLs):
content/
├── index.md # → /
├── posts/
│ ├── index.md # → /posts/
│ └── 001-my-post/
│ └── index.md # → /posts/my-post/
├── 01-about/
│ └── index.md # → /about/
├── 02-projects/
│ └── index.md # → /projects/
└── drafts/ # Ignored (add to ignorePatterns)
---
title: "My Amazing Post"
date: 2025-01-15
tags:
- thoughts
- learning
draft: false
---Edit the theme colors in quartz.config.ts:
theme: {
colors: {
lightMode: {
light: "#ffffff",
dark: "#313131",
secondary: "#268bd2", // Link color
// ... see full options in config
},
darkMode: {
// ... dark mode colors
},
},
}The signature blue sidebar color is defined in quartz/styles/custom.scss:
.sidebar.right {
background-color: #234bc2 !important; // Hugo theme-base-02
}theme: {
typography: {
header: "PT Sans",
body: "PT Sans",
code: "IBM Plex Mono",
},
}Include posts from multiple folders:
// In contentPage.tsx
pageBody: PostsListWithFilter({
targetSlugs: ["index", "posts/index"],
postsPrefixes: ["posts/", "thoughts/", "projects/"],
})Hide components on specific pages using the helper functions in quartz.layout.ts:
// Hide on posts list pages
Component.ConditionalRender({
component: Component.ContentMeta(),
condition: (page) => !["index", "posts/index"].includes(page.fileData.slug ?? ""),
})
// Show only on content pages (not section indexes)
Component.ConditionalRender({
component: Component.TableOfContents(),
condition: (page) => {
const slug = page.fileData.slug ?? ""
if (slug === "index") return false
const parts = slug.split("/")
return !(parts.length === 2 && parts[1] === "index")
},
})For links that shouldn't use SPA navigation (like tag filters), add data-router-ignore:
<a href="#" data-router-ignore data-tag="thoughts">thoughts</a>Make sure you're using Node.js >= 22:
node --version # Should be v22.x or higherClear the build cache and rebuild:
rm -rf public/
npx quartz buildThe mobile navigation requires JavaScript. Make sure enableSPA: true in your config for proper script loading.
- Built on Quartz v4 by Jacky Zhao
- Inspired by Hugo Lanyon theme
- Typography powered by PT Sans and IBM Plex Mono
MIT License - feel free to use this theme for your own digital garden!
"[One] who works with the door open gets all kinds of interruptions, but [they] also occasionally gets clues as to what the world is and what might be important." — Richard Hamming
Happy gardening! 🌱