๐ฑ a fast, batteries-included static-site generator that transforms Markdown content into fully functional websites
---
title: AliasRedirects
description: Generates redirect pages from frontmatter aliases and case-preserving URLs.
tags:
- plugin/emitter
image: https://images.unsplash.com/photo-1601735479770-bb5de9dbe844
repository: "[quartz-community/alias-redirects](https://github.com/quartz-community/alias-redirects)"
enabled: true
required: false
---
This plugin emits HTML redirect pages so that old URLs redirect to the canonical page. It handles two types of redirects:
1. **Frontmatter aliases**: Redirect pages for aliases defined in your content's frontmatter.
2. **Case-preserving redirects**: Automatic redirect pages for URLs that changed due to Quartz v5's lowercase slug normalization.
### Frontmatter Aliases
If `foo.md` has the following frontmatter:
```md title="foo.md"
---
title: "Foo"
aliases:
- "bar"
---
```
The target `host.me/bar` will be permanently redirected to `host.me/foo`.
The emitter supports the following frontmatter fields:
- `aliases`
- `alias`
### Case-Preserving Redirects
Quartz v5 normalizes all URLs to lowercase. If you are migrating from v4 (which preserved the original casing), previously indexed URLs containing uppercase letters (e.g. `/Diary/My-Note`) would return 404 errors.
When `enableCaseRedirects` is enabled (the default), this plugin automatically detects files whose original path differs from the lowercased slug and generates redirect pages at the original-case URL. For example, if your content directory contains `Diary/2026-01-01.md`, the plugin generates:
- The canonical page at `/diary/2026-01-01` (produced by the normal build)
- A redirect page at `/Diary/2026-01-01` (produced by this plugin)
The redirect page includes proper SEO signals:
- `<meta http-equiv="refresh" content="0; url=...">` for an instant redirect
- `<link rel="canonical">` pointing to the lowercase URL
- `<meta name="robots" content="noindex">` to prevent duplicate indexing
This preserves search engine rankings and ensures inbound links continue to work.
> [!note]
> Case-preserving redirects have no effect on case-insensitive filesystems (macOS, Windows) where the server already resolves either casing to the same file. The plugin automatically detects the filesystem type and skips redirect generation when unnecessary.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
- `enableCaseRedirects`: If `true` (default), automatically generates redirect pages for URLs that changed casing due to v5's lowercase normalization. Set to `false` to disable this behavior.
## API
- Category: Emitter
- Function name: `ExternalPlugin.AliasRedirects()`.
- Source: [`quartz-community/alias-redirects`](https://github.com/quartz-community/alias-redirects)
- Install: `npx quartz plugin add github:quartz-community/alias-redirects`
---
title: ArticleTitle
description: Renders the article title as an h1 heading.
tags:
- plugin/component
image:
repository: "[quartz-community/article-title](https://github.com/quartz-community/article-title)"
enabled: true
required: false
---
This plugin renders the article title from the page's frontmatter as an `<h1>` heading at the top of the page content. It reads the `title` field from frontmatter (falling back to the filename if no title is set).
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.
## API
- Category: Component
- Function name: `ExternalPlugin.ArticleTitle()`.
- Source: [`quartz-community/article-title`](https://github.com/quartz-community/article-title)
- Install: `npx quartz plugin add github:quartz-community/article-title`
---
title: Assets
tags:
- plugin/emitter
image: https://images.unsplash.com/photo-1526304640581-d334cdbbf45e
---
This plugin emits all non-Markdown static assets in your content folder (like images, videos, HTML, etc). The plugin respects the `ignorePatterns` in the global [[configuration]].
Note that all static assets will then be accessible through its path on your generated site, i.e: `host.me/path/to/static.pdf`
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.
## API
- Category: Emitter
- Function name: `Plugin.Assets()` (internal plugin).
- Source: [`quartz/plugins/emitters/assets.ts`](https://github.com/jackyzha0/quartz/blob/v5/quartz/plugins/emitters/assets.ts).
---
title: Backlinks
description: Shows pages that link to the current page.
tags:
- plugin/component
image:
repository: "[quartz-community/backlinks](https://github.com/quartz-community/backlinks)"
enabled: true
required: false
---
Shows pages that link to the current page.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
See [[plugins/Backlinks]] for detailed usage information.
## Configuration
This plugin accepts the following configuration options:
- `hideWhenEmpty`: Hide the backlinks section if the current page has no backlinks. Defaults to `true`.
### Default options
```yaml title="quartz.config.yaml"
- source: github:quartz-community/backlinks
enabled: true
options:
hideWhenEmpty: true
```
## API
- Category: Component
- Function name: `ExternalPlugin.Backlinks()`.
- Source: [`quartz-community/backlinks`](https://github.com/quartz-community/backlinks)
- Install: `npx quartz plugin add github:quartz-community/backlinks`
---
title: BasesPage
description: Renders Obsidian Bases files as database-style views.
tags:
- plugin/pageType
- plugin/component
image:
new-in-v5: true
repository: "[quartz-community/bases-page](https://github.com/quartz-community/bases-page)"
enabled: true
required: false
---
This plugin provides support for [Obsidian Bases](https://obsidian.md/changelog/2025-04-15-desktop-v1.8.0/) (`.base` files) in Quartz. It reads `.base` files from your vault, resolves matching notes based on the query definition, and renders them as interactive database-like views with support for tables, lists, cards, and maps. It uses the `default` [[layout#Page Frames|page frame]] (three-column layout with sidebars).
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
## Features
- **Table view**: Sortable columns with automatic type rendering (strings, numbers, booleans, arrays, links).
- **List view**: Compact list with metadata chips for each entry.
- **Cards view**: Card layout with optional image property support.
- **Map view**: Placeholder for future map-based visualization.
- **Multiple views**: A single `.base` file can define multiple views, displayed as switchable tabs.
- **Filters**: Recursive filter trees with `and`/`or`/`not` operators.
- **Formulas**: Computed properties via formula expressions.
- **Summaries**: Column-level aggregations (Sum, Average, Min, Max, Median, etc.).
- **Property configuration**: Custom display names for properties.
- **Link rendering**: Wikilinks and Markdown links within cell values are rendered as clickable links.
## Interaction with `unlisted` pages
`BasesPage` respects the `file.data.unlisted` convention written by [[UnlistedPages]] and [[EncryptedPages]]. Pages marked `unlisted: true` (or encrypted pages with `stealth: true`) are excluded from every rendered base view โ table, list, board, cards, gallery, and any custom view โ regardless of whether the base's filter expression would match them. Unlisted pages also cannot be dereferenced from formulas on visible pages via `.asFile()`.
> [!note]
> Base views are **server-side rendered** HTML baked at build time. They do not update client-side after a visitor decrypts an encrypted page. Graph, explorer, and search all re-hydrate from the patched in-memory content index and show newly-unlocked pages for the rest of the browser session โ base views do not, because they were materialized at build time with unlisted pages already excluded. A visitor who successfully decrypts a revealable encrypted page will see it appear in graph, explorer, and search, but **not** in any base view, until the site is rebuilt with that page listed. This is the same structural limitation that applies to backlinks, recent notes, folder listings, and tag listings.
## Configuration
This plugin accepts the following configuration options:
- `defaultViewType`: The default view type when none is specified in the `.base` file. Defaults to `"table"`.
- `linkResolution`: How to resolve internal links in view renderers. Should match the `markdownLinkResolution` setting of the [[CrawlLinks]] plugin. Can be `"absolute"`, `"relative"`, or `"shortest"`. Defaults to `"shortest"`.
- `customViews`: A map of custom view renderers. Keys are view type names. These override built-in renderers for the same type, or add new view types. Requires a TS override.
### Default options
```yaml title="quartz.config.yaml"
- source: github:quartz-community/bases-page
enabled: true
```
For custom view renderers, use a TS override in `quartz.ts`:
```ts title="quartz.ts (override)"
import * as ExternalPlugin from "./.quartz/plugins"
// Must be placed before loadQuartzConfig()
ExternalPlugin.BasesPage({
defaultViewType: "table",
customViews: {
myView: ({ entries, view, basesData, total, locale }) => {
// return JSX
},
},
})
```
## API
- Category: Page Type, Component
- Function name: `ExternalPlugin.BasesPage()`.
- Source: [`quartz-community/bases-page`](https://github.com/quartz-community/bases-page)
- Install: `npx quartz plugin add github:quartz-community/bases-page`
---
title: Breadcrumbs
description: Breadcrumb navigation trail.
tags:
- plugin/component
image:
repository: "[quartz-community/breadcrumbs](https://github.com/quartz-community/breadcrumbs)"
enabled: true
required: false
---
Navigation breadcrumb trail.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
See [[plugins/Breadcrumbs]] for detailed usage information.
## Configuration
This plugin accepts the following configuration options:
- `spacerSymbol`: The symbol to use between breadcrumb items. Defaults to `"โฏ"`.
- `rootName`: The name of the root page. Defaults to `Home`.
- `resolveFrontmatterTitle`: Whether to use the `title` frontmatter field for breadcrumb items. Defaults to `true`.
- `showCurrentPage`: Whether to show the current page in the breadcrumb trail. Defaults to `true`.
### Default options
```yaml title="quartz.config.yaml"
- source: github:quartz-community/breadcrumbs
enabled: true
options:
spacerSymbol: "โฏ"
rootName: Home
resolveFrontmatterTitle: true
showCurrentPage: true
```
## API
- Category: Component
- Function name: `ExternalPlugin.Breadcrumbs()`.
- Source: [`quartz-community/breadcrumbs`](https://github.com/quartz-community/breadcrumbs)
- Install: `npx quartz plugin add github:quartz-community/breadcrumbs`
---
title: CanvasPage
description: Renders JSON Canvas files as interactive, pannable pages.
tags:
- plugin/pageType
image: "#7852ee"
new-in-v5: true
repository: "[quartz-community/canvas-page](https://github.com/quartz-community/canvas-page)"
enabled: true
required: false
---
This plugin is a page type plugin that renders [JSON Canvas](https://jsoncanvas.org) (`.canvas`) files as interactive, pannable and zoomable canvas pages. It uses a custom `"canvas"` [[layout#Page Frames|page frame]] that provides a fullscreen, always-on canvas experience with a togglable left sidebar for navigation. It supports the full [JSON Canvas 1.0 spec](https://jsoncanvas.org/spec/1.0/), including text nodes with Markdown rendering, file nodes that link to other pages in your vault, link nodes for external URLs, and group nodes for visual organization. Edges between nodes are rendered as SVG paths with optional labels, arrow markers, and colors.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
- `enableInteraction`: Whether to enable pan and zoom interaction on the canvas. Default: `true{:ts}`.
- `initialZoom`: The initial zoom level when the canvas is first displayed. Default: `1{:ts}`.
- `minZoom`: The minimum zoom level allowed when zooming out. Default: `0.1{:ts}`.
- `maxZoom`: The maximum zoom level allowed when zooming in. Default: `5{:ts}`.
### Canvas Frame
The canvas-page plugin provides its own `"canvas"` page frame via the [[layout#Page Frames|Frame Registry]]. This frame:
- Renders the canvas in **fullscreen mode** by default (100vw ร 100vh), giving the canvas maximum screen space โ leaning into the "endless canvas" concept of JSON Canvas.
- Provides a **togglable left sidebar** that slides in from the left edge. This is the only layout slot available โ it renders the same components as the `left` sidebar on content pages (e.g., Explorer, Search, Page Title).
- The sidebar toggle button (hamburger/close icon) is positioned in the top-left corner.
- Canvas controls (zoom in, zoom out, reset) are positioned on the right side.
- On mobile, the sidebar overlays the canvas rather than pushing it aside.
Users can override this frame via `quartz.config.yaml` if needed:
```yaml title="quartz.config.yaml"
layout:
byPageType:
canvas:
template: default # Use standard three-column layout instead
```
### Features
- **Text nodes**: Render Markdown content including headings, bold, italic, strikethrough, lists, links, and code blocks via [GFM](https://github.github.com/gfm/) support.
- **File nodes**: Link to other pages in your vault. Supports popover previews on hover.
- **Link nodes**: Reference external URLs.
- **Group nodes**: Visual grouping containers with optional labels and background colors.
- **Edges**: SVG connections between nodes with optional labels, arrow markers, and colors. Supports all four sides (top, right, bottom, left) and both preset colors (1โ6) and custom hex colors.
- **Togglable sidebar**: Hamburger button in the top-left corner toggles the left sidebar for navigation. Press `Escape` or click the close button to dismiss.
- **Preset colors**: Six preset colors (red, orange, yellow, green, cyan, purple) plus custom hex colors (`#RRGGBB`) for nodes and edges.
## API
- Category: Page Type
- Function name: `ExternalPlugin.CanvasPage()`.
- Source: [`quartz-community/canvas-page`](https://github.com/quartz-community/canvas-page)
- Install: `npx quartz plugin add github:quartz-community/canvas-page`
---
title: Citations
description: Academic citation and bibliography support via BibTeX.
tags:
- plugin/transformer
image: https://images.unsplash.com/photo-1582079133805-43655f026448
repository: "[quartz-community/citations](https://github.com/quartz-community/citations)"
enabled: false
required: false
---
This plugin adds Citation support to Quartz.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
- `bibliographyFile`: the path to the bibliography file. Defaults to `./bibliography.bib`. This is relative to git source of your vault.
- `suppressBibliography`: whether to suppress the bibliography at the end of the document. Defaults to `false`.
- `linkCitations`: whether to link citations to the bibliography. Defaults to `false`.
- `csl`: the citation style to use. Defaults to `apa`. Reference [rehype-citation](https://rehype-citation.netlify.app/custom-csl) for more options.
## API
- Category: Transformer
- Function name: `ExternalPlugin.Citations()`.
- Source: [`quartz-community/citations`](https://github.com/quartz-community/citations)
- Install: `npx quartz plugin add github:quartz-community/citations`
---
title: CNAME
description: Emits a CNAME file for custom domain deployment.
tags:
- plugin/emitter
image:
repository: "[quartz-community/cname](https://github.com/quartz-community/cname)"
enabled: true
required: false
---
This plugin emits a `CNAME` record that points your subdomain to the default domain of your site.
If you want to use a custom domain name like `quartz.example.com` for the site, then this is needed.
See [[hosting|Hosting]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.
## API
- Category: Emitter
- Function name: `ExternalPlugin.CNAME()`.
- Source: [`quartz-community/cname`](https://github.com/quartz-community/cname)
- Install: `npx quartz plugin add github:quartz-community/cname`
---
title: Comments
description: Comment system integration (Giscus, Utterances, etc.).
tags:
- plugin/component
image: "[[giscus-results.png]]"
repository: "[quartz-community/comments](https://github.com/quartz-community/comments)"
enabled: false
required: false
---
Comment system (giscus, utterances, etc.).
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
See [[plugins/Comments]] for detailed usage information.
## Configuration
This plugin accepts the following configuration options:
- `provider`: The comment provider to use. Currently only `giscus` is supported.
- `options`: Provider-specific options.
- `repo`: The GitHub repository to use for comments.
- `repoId`: The ID of the GitHub repository.
- `category`: The discussion category to use.
- `categoryId`: The ID of the discussion category.
- `lang`: The language for the comment system. Defaults to `en`.
- `themeUrl`: URL to a folder with custom themes.
- `lightTheme`: Filename for the light theme CSS file. Defaults to `light`.
- `darkTheme`: Filename for the dark theme CSS file. Defaults to `dark`.
- `mapping`: How to map pages to discussions. Defaults to `url`.
- `strict`: Use strict title matching. Defaults to `true`.
- `reactionsEnabled`: Whether to enable reactions for the main post. Defaults to `true`.
- `inputPosition`: Where to put the comment input box relative to the comments. Defaults to `bottom`.
### Default options
```yaml title="quartz.config.yaml"
- source: github:quartz-community/comments
enabled: true
options:
provider: giscus
options:
repo: jackyzha0/quartz
repoId: MDEwOlJlcG9zaXRvcnkzODcyMTMyMDg
category: Announcements
categoryId: DIC_kwDOFxRnmM4B-Xg6
lang: en
```
## API
- Category: Component
- Function name: `ExternalPlugin.Comments()`.
- Source: [`quartz-community/comments`](https://github.com/quartz-community/comments)
- Install: `npx quartz plugin add github:quartz-community/comments`
---
title: ComponentResources
tags:
- plugin/emitter
image:
---
This plugin manages and emits the static resources required for the Quartz framework. This includes CSS stylesheets and JavaScript scripts that enhance the functionality and aesthetics of the generated site. See also the `cdnCaching` option in the `theme` section of the [[configuration]].
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.
## API
- Category: Emitter
- Function name: `Plugin.ComponentResources()` (internal plugin).
- Source: [`quartz/plugins/emitters/componentResources.ts`](https://github.com/jackyzha0/quartz/blob/v5/quartz/plugins/emitters/componentResources.ts).
---
title: ContentIndex
description: Generates sitemap, RSS feed, and content index.
tags:
- plugin/emitter
image:
repository: "[quartz-community/content-index](https://github.com/quartz-community/content-index)"
enabled: true
required: false
---
This plugin emits both RSS and an XML sitemap for your site. The [[RSS Feed]] allows users to subscribe to content on your site and the sitemap allows search engines to better index your site. The plugin also emits a `contentIndex.json` file which is used by dynamic frontend components like search and graph.
This plugin emits a comprehensive index of the site's content, generating additional resources such as a sitemap, an RSS feed, and a
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
- `enableSiteMap`: If `true` (default), generates a sitemap XML file (`sitemap.xml`) listing all site URLs for search engines in content discovery.
- `enableRSS`: If `true` (default), produces an RSS feed (`index.xml`) with recent content updates.
- `rssLimit`: Defines the maximum number of entries to include in the RSS feed, helping to focus on the most recent or relevant content. Defaults to `10`.
- `rssFullHtml`: If `true`, the RSS feed includes the full rendered HTML content of each page. Defaults to `false`.
- `rssSlug`: Slug to the generated RSS feed XML file. Defaults to `"index"`.
- `includeEmptyFiles`: If `true` (default), content files with no body text are included in the generated index and resources.
## API
- Category: Emitter
- Function name: `ExternalPlugin.ContentIndex()`.
- Source: [`quartz-community/content-index`](https://github.com/quartz-community/content-index)
- Install: `npx quartz plugin add github:quartz-community/content-index`
---
title: ContentMeta
description: Displays creation date and reading time.
tags:
- plugin/component
image:
repository: "[quartz-community/content-meta](https://github.com/quartz-community/content-meta)"
enabled: true
required: false
---
This plugin displays content metadata below the article title, such as the creation date and estimated reading time.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
## Configuration
This plugin accepts the following configuration options:
- `showReadingTime`: Whether to display the estimated reading time. Defaults to `true`.
- `showComma`: Whether to display a comma between metadata items. Defaults to `true`.
### Default options
```yaml title="quartz.config.yaml"
- source: github:quartz-community/content-meta
enabled: true
options:
showReadingTime: true
showComma: true
```
## API
- Category: Component
- Function name: `ExternalPlugin.ContentMeta()`.
- Source: [`quartz-community/content-meta`](https://github.com/quartz-community/content-meta)
- Install: `npx quartz plugin add github:quartz-community/content-meta`
---
title: ContentPage
description: Generates HTML pages for Markdown content.
tags:
- plugin/pageType
image:
repository: "[quartz-community/content-page](https://github.com/quartz-community/content-page)"
enabled: true
required: false
---
This plugin is a page type plugin for the Quartz framework. It generates the HTML pages for each piece of Markdown content. It emits the full-page [[layout]], including headers, footers, and body content, among others. It uses the `default` [[layout#Page Frames|page frame]] (three-column layout with sidebars). It is now configured in the `pageTypes` section of `quartz.config.yaml`.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.
## API
- Category: Page Type
- Function name: `ExternalPlugin.ContentPage()`.
- Source: [`quartz-community/content-page`](https://github.com/quartz-community/content-page)
- Install: `npx quartz plugin add github:quartz-community/content-page`
---
title: CrawlLinks
description: Parses and resolves internal links. Removing it is not recommended.
tags:
- plugin/transformer
image:
repository: "[quartz-community/crawl-links](https://github.com/quartz-community/crawl-links)"
enabled: true
required: true
---
This plugin parses links and processes them to point to the right places. It is also needed for embedded links (like images). See [[Obsidian compatibility]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
- `markdownLinkResolution`: Sets the strategy for resolving Markdown paths, can be `"absolute"` (default), `"relative"` or `"shortest"`. You should use the same setting here as in [[Obsidian compatibility|Obsidian]].
- `absolute`: Path relative to the root of the content folder.
- `relative`: Path relative to the file you are linking from.
- `shortest`: Name of the file. If this isn't enough to identify the file, use the full absolute path.
- `prettyLinks`: If `true` (default), simplifies links by removing folder paths, making them more user friendly (e.g. `folder/deeply/nested/note` becomes `note`).
- `openLinksInNewTab`: If `true`, configures external links to open in a new tab. Defaults to `false`.
- `lazyLoad`: If `true`, adds lazy loading to resource elements (`img`, `video`, etc.) to improve page load performance. Defaults to `false`.
- `externalLinkIcon`: Adds an icon next to external links when `true` (default) to visually distinguishing them from internal links.
- `disableBrokenWikilinks`: If `true`, internal links whose resolved slug is not present in the site (i.e. no matching file under `markdownLinkResolution`) gain an additional `broken` CSS class alongside `internal`, so they can be styled distinctly. Defaults to `false`. Applies to both wikilinks and regular Markdown links, since both are indistinguishable `<a>` elements by the time this plugin runs.
> [!warning]
> Removing this plugin is _not_ recommended and will likely break the page.
## API
- Category: Transformer
- Function name: `ExternalPlugin.CrawlLinks()`.
- Source: [`quartz-community/crawl-links`](https://github.com/quartz-community/crawl-links)
- Install: `npx quartz plugin add github:quartz-community/crawl-links`
---
title: CreatedModifiedDate
description: Determines creation and modification dates from frontmatter, git, or filesystem.
tags:
- plugin/transformer
image:
repository: "[quartz-community/created-modified-date](https://github.com/quartz-community/created-modified-date)"
enabled: true
required: false
---
This plugin determines the created, modified, and published dates for a document using three potential data sources: frontmatter metadata, Git history, and the filesystem. See [[authoring content#Syntax]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
- `priority`: The data sources to consult for date information. Highest priority first. Possible values are `"frontmatter"`, `"git"`, and `"filesystem"`. Defaults to `["frontmatter", "git", "filesystem"]`.
- `defaultDateType`: Which date type to use when displaying dates. Can be `"created"`, `"modified"`, or `"published"`. Defaults to `"modified"`.
When loading the frontmatter, the value of [[Frontmatter#List]] is used.
> [!warning]
> If you rely on `git` for dates, make sure `defaultDateType` is set to `modified` in the plugin's options.
>
> Depending on how you [[hosting|host]] your Quartz, the `filesystem` dates of your local files may not match the final dates. In these cases, it may be better to use `git` or `frontmatter` to guarantee correct dates.
## API
- Category: Transformer
- Function name: `ExternalPlugin.CreatedModifiedDate()`.
- Source: [`quartz-community/created-modified-date`](https://github.com/quartz-community/created-modified-date)
- Install: `npx quartz plugin add github:quartz-community/created-modified-date`
---
title: Custom OG Images
description: Generates Open Graph social preview images.
tags:
- feature/emitter
image: "[[social-image-preview-dark.png]]"
repository: "[quartz-community/og-image](https://github.com/quartz-community/og-image)"
enabled: true
required: false
---
The Custom OG Images emitter plugin generates social media preview images for your pages. It uses [satori](https://github.com/vercel/satori) to convert HTML/CSS into images, allowing you to create beautiful and consistent social media preview cards for your content.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
## Features
- Automatically generates social media preview images for each page
- Supports both light and dark mode themes
- Customizable through frontmatter properties
- Fallback to default image when needed
- Full control over image design through custom components
## Configuration
> [!info] Info
>
> The `baseUrl` property in your [[configuration]] must be set properly for social images to work correctly, as they require absolute paths.
This plugin accepts the following configuration options:
```yaml title="quartz.config.yaml"
plugins:
- source: github:quartz-community/og-image
enabled: true
options:
colorScheme: lightMode # "lightMode" or "darkMode"
width: 1200
height: 630
excludeRoot: false
```
For the TS override approach (needed for custom `imageStructure`):
```ts title="quartz.ts (override)"
import * as ExternalPlugin from "./.quartz/plugins"
import { defaultImage } from "./quartz/plugins/emitters/ogImage"
// Must be placed before loadQuartzConfig()
ExternalPlugin.CustomOgImages({
colorScheme: "lightMode",
width: 1200,
height: 630,
excludeRoot: false,
imageStructure: defaultImage,
})
```
### Configuration Options
| Option | Type | Default | Description |
| -------------------- | --------- | ------------------------- | ----------------------------------------------------------------- |
| `colorScheme` | string | "lightMode" | Theme to use for generating images ("darkMode" or "lightMode") |
| `width` | number | 1200 | Width of the generated image in pixels |
| `height` | number | 630 | Height of the generated image in pixels |
| `excludeRoot` | boolean | false | Whether to exclude the root index page from auto-generated images |
| `defaultTitle` | string | "Untitled" | Fallback title when a page has no title |
| `defaultDescription` | string | "No description provided" | Fallback description when a page has no description |
| `imageStructure` | component | defaultImage | Custom component to use for image generation |
## Frontmatter Properties
The following properties can be used to customize your link previews:
| Property | Alias | Summary |
| ------------------- | ---------------- | ----------------------------------- |
| `socialDescription` | `description` | Description to be used for preview. |
| `socialImage` | `image`, `cover` | Link to preview image. |
The `socialImage` property should contain a link to an image either relative to `quartz/static`, or a full URL. If you have a folder for all your images in `quartz/static/my-images`, an example for `socialImage` could be `"my-images/cover.png"`. Alternatively, you can use a fully qualified URL like `"https://example.com/cover.png"`.
> [!info] Info
>
> The priority for what image will be used for the cover image looks like the following: `frontmatter property > generated image (if enabled) > default image`.
>
> The default image (`quartz/static/og-image.png`) will only be used as a fallback if nothing else is set. If the Custom OG Images emitter plugin is enabled, it will be treated as the new default per page, but can be overwritten by setting the `socialImage` frontmatter property for that page.
## Customization
You can fully customize how the images being generated look by passing your own component to `imageStructure`. This component takes JSX + some page metadata/config options and converts it to an image using [satori](https://github.com/vercel/satori). Vercel provides an [online playground](https://og-playground.vercel.app/) that can be used to preview how your JSX looks like as a picture. This is ideal for prototyping your custom design.
### Fonts
You will also be passed an array containing a header and a body font (where the first entry is header and the second is body). The fonts matches the ones selected in `theme.typography.header` and `theme.typography.body` from `quartz.config.yaml` and will be passed in the format required by [`satori`](https://github.com/vercel/satori). To use them in CSS, use the `.name` property (e.g. `fontFamily: fonts[1].name` to use the "body" font family).
An example of a component using the header font could look like this:
```tsx title="socialImage.tsx"
export const myImage: SocialImageOptions["imageStructure"] = (...) => {
return <p style={{ fontFamily: fonts[0].name }}>Cool Header!</p>
}
```
> [!example]- Local fonts
>
> For cases where you use a local fonts under `static` folder, make sure to set the correct `@font-face` in `custom.scss`
>
> ```scss title="custom.scss"
> @font-face {
> font-family: "Newsreader";
> font-style: normal;
> font-weight: normal;
> font-display: swap;
> src: url("/static/Newsreader.woff2") format("woff2");
> }
> ```
>
> Then in `quartz/util/og.tsx`, you can load the Satori fonts like so:
>
> ```tsx title="quartz/util/og.tsx"
> import { joinSegments, QUARTZ } from "../path"
> import fs from "fs"
> import path from "path"
>
> const newsreaderFontPath = joinSegments(QUARTZ, "static", "Newsreader.woff2")
> export async function getSatoriFonts(headerFont: FontSpecification, bodyFont: FontSpecification) {
> // ... rest of implementation remains same
> const fonts: SatoriOptions["fonts"] = [
> ...headerFontData.map((data, idx) => ({
> name: headerFontName,
> data,
> weight: headerWeights[idx],
> style: "normal" as const,
> })),
> ...bodyFontData.map((data, idx) => ({
> name: bodyFontName,
> data,
> weight: bodyWeights[idx],
> style: "normal" as const,
> })),
> {
> name: "Newsreader",
> data: await fs.promises.readFile(path.resolve(newsreaderFontPath)),
> weight: 400,
> style: "normal" as const,
> },
> ]
>
> return fonts
> }
> ```
>
> This font then can be used with your custom structure.
## Examples
Here are some example image components you can use as a starting point:
### Basic Example
This example will generate images that look as follows:
| Light | Dark |
| ------------------------------------------ | ----------------------------------------- |
| ![[custom-social-image-preview-light.png]] | ![[custom-social-image-preview-dark.png]] |
```tsx
import { SatoriOptions } from "satori/wasm"
import { GlobalConfiguration } from "../cfg"
import { SocialImageOptions, UserOpts } from "./imageHelper"
import { QuartzPluginData } from "../plugins/vfile"
export const customImage: SocialImageOptions["imageStructure"] = (
cfg: GlobalConfiguration,
userOpts: UserOpts,
title: string,
description: string,
fonts: SatoriOptions["fonts"],
fileData: QuartzPluginData,
) => {
// How many characters are allowed before switching to smaller font
const fontBreakPoint = 22
const useSmallerFont = title.length > fontBreakPoint
const { colorScheme } = userOpts
return (
<div
style={{
display: "flex",
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "center",
height: "100%",
width: "100%",
}}
>
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
height: "100%",
width: "100%",
backgroundColor: cfg.theme.colors[colorScheme].light,
flexDirection: "column",
gap: "2.5rem",
paddingTop: "2rem",
paddingBottom: "2rem",
}}
>
<p
style={{
color: cfg.theme.colors[colorScheme].dark,
fontSize: useSmallerFont ? 70 : 82,
marginLeft: "4rem",
textAlign: "center",
marginRight: "4rem",
fontFamily: fonts[0].name,
}}
>
{title}
</p>
<p
style={{
color: cfg.theme.colors[colorScheme].dark,
fontSize: 44,
marginLeft: "8rem",
marginRight: "8rem",
lineClamp: 3,
fontFamily: fonts[1].name,
}}
>
{description}
</p>
</div>
<div
style={{
height: "100%",
width: "2vw",
position: "absolute",
backgroundColor: cfg.theme.colors[colorScheme].tertiary,
opacity: 0.85,
}}
/>
</div>
)
}
```
### Advanced Example
The following example includes a customized social image with a custom background and formatted date:
```typescript title="custom-og.tsx"
export const og: SocialImageOptions["Component"] = (
cfg: GlobalConfiguration,
fileData: QuartzPluginData,
{ colorScheme }: Options,
title: string,
description: string,
fonts: SatoriOptions["fonts"],
) => {
let created: string | undefined
let reading: string | undefined
if (fileData.dates) {
created = formatDate(getDate(cfg, fileData)!, cfg.locale)
}
const { minutes, text: _timeTaken, words: _words } = readingTime(fileData.text!)
reading = i18n(cfg.locale).components.contentMeta.readingTime({
minutes: Math.ceil(minutes),
})
const Li = [created, reading]
return (
<div
style={{
position: "relative",
display: "flex",
flexDirection: "row",
alignItems: "flex-start",
height: "100%",
width: "100%",
backgroundImage: `url("https://${cfg.baseUrl}/static/og-image.jpeg")`,
backgroundSize: "100% 100%",
}}
>
<div
style={{
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
background: "radial-gradient(circle at center, transparent, rgba(0, 0, 0, 0.4) 70%)",
}}
/>
<div
style={{
display: "flex",
height: "100%",
width: "100%",
flexDirection: "column",
justifyContent: "flex-start",
alignItems: "flex-start",
gap: "1.5rem",
paddingTop: "4rem",
paddingBottom: "4rem",
marginLeft: "4rem",
}}
>
<img
src={`"https://${cfg.baseUrl}/static/icon.jpeg"`}
style={{
position: "relative",
backgroundClip: "border-box",
borderRadius: "6rem",
}}
width={80}
/>
<div
style={{
display: "flex",
flexDirection: "column",
textAlign: "left",
fontFamily: fonts[0].name,
}}
>
<h2
style={{
color: cfg.theme.colors[colorScheme].light,
fontSize: "3rem",
fontWeight: 700,
marginRight: "4rem",
fontFamily: fonts[0].name,
}}
>
{title}
</h2>
<ul
style={{
color: cfg.theme.colors[colorScheme].gray,
gap: "1rem",
fontSize: "1.5rem",
fontFamily: fonts[1].name,
}}
>
{Li.map((item, index) => {
if (item) {
return <li key={index}>{item}</li>
}
})}
</ul>
</div>
<p
style={{
color: cfg.theme.colors[colorScheme].light,
fontSize: "1.5rem",
overflow: "hidden",
marginRight: "8rem",
textOverflow: "ellipsis",
display: "-webkit-box",
WebkitLineClamp: 7,
WebkitBoxOrient: "vertical",
lineClamp: 7,
fontFamily: fonts[1].name,
}}
>
{description}
</p>
</div>
</div>
)
}
```
## API
- Category: Emitter
- Function name: `ExternalPlugin.CustomOgImages()`.
- Source: [`quartz-community/og-image`](https://github.com/quartz-community/og-image)
- Install: `npx quartz plugin add github:quartz-community/og-image`
---
title: Darkmode
description: Toggle between light and dark themes.
tags:
- plugin/component
image: "#0052cc"
repository: "[quartz-community/darkmode](https://github.com/quartz-community/darkmode)"
enabled: true
required: false
---
Dark mode toggle.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
See [[plugins/Darkmode]] for detailed usage information.
## Configuration
This plugin accepts the following configuration options:
- `enabled`: Whether to enable the dark mode toggle. Defaults to `true`.
### Default options
```yaml title="quartz.config.yaml"
- source: github:quartz-community/darkmode
enabled: true
```
## API
- Category: Component
- Function name: `ExternalPlugin.Darkmode()`.
- Source: [`quartz-community/darkmode`](https://github.com/quartz-community/darkmode)
- Install: `npx quartz plugin add github:quartz-community/darkmode`
---
title: Description
description: Generates page descriptions for metadata and previews.
tags:
- plugin/transformer
image:
repository: "[quartz-community/description](https://github.com/quartz-community/description)"
enabled: true
required: false
---
This plugin generates descriptions that are used as metadata for the HTML `head`, the [[RSS Feed]] and in [[folder and tag listings]] if there is no main body content, the description is used as the text between the title and the listing.
If the frontmatter contains a `description` property, it is used (see [[authoring content#Syntax]]). Otherwise, the plugin will do its best to use the first few sentences of the content to reach the target description length.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
- `descriptionLength`: the target length of the generated description. Default is 150 characters. The cut off happens after the first _sentence_ that ends after the given length.
- `maxDescriptionLength`: the hard maximum length of the description. If the generated description exceeds this, it is truncated with an ellipsis. Default is 300 characters.
- `replaceExternalLinks`: If `true` (default), replace external links with their domain and path in the description (e.g. `https://domain.tld/some_page/another_page?query=hello&target=world` is replaced with `domain.tld/some_page/another_page`).
## API
- Category: Transformer
- Function name: `ExternalPlugin.Description()`.
- Source: [`quartz-community/description`](https://github.com/quartz-community/description)
- Install: `npx quartz plugin add github:quartz-community/description`
---
title: Encrypted Pages Demo
password: quartz
unlisted: true
tags:
- plugin/transformer
image:
---
Congratulations! You've successfully decrypted this page. ๐
This is a live demo of the [[EncryptedPages]] plugin. The content you're reading was encrypted at build time using AES-256-GCM and decrypted in your browser using the Web Crypto API. This page is also `unlisted: true`, which means it was hidden from every discovery surface on the site until you entered the password.
## What just happened?
1. At build time, the plugin read the `password` field from this page's frontmatter and encrypted all content below the title.
2. Because this page is `unlisted: true`, the plugin emitted its metadata (slug, title, links, tags) to a separate `static/encryptedContentIndex.json` file, encrypted with this page's own password.
3. When you visited this page, you were shown a password prompt instead of the content. The page was absent from the sidebar graph, explorer, search, RSS, sitemap, backlinks, tag listings, and bases views.
4. After entering the correct password, the plugin derived an encryption key using PBKDF2 and decrypted the content client-side.
5. The plugin then used the cached password to unlock this page's entry in the shadow content index and patched the in-memory content index in place. A `content-index-updated` event was dispatched, so graph, explorer, and search re-initialized with the newly unlocked entry โ if you navigate back to any other page now, you will see this page in the sidebar, the graph, and search results. Server-side rendered listings (backlinks, recent notes, tag pages, folder listings, and [[BasesPage|bases views]]) were baked into HTML at build time and will not update within this session; they will only reflect decrypted pages on a fresh build of the site.
## Password caching
Your password has been cached in session storage. If there were other encrypted pages on this site with the same password, the plugin would automatically try this password on each one โ unlocking its content as well as its entry in the shadow content index โ so you'd only need to enter it once per session.
## Try it yourself
To add encrypted pages to your own Quartz site, install the plugin and add a `password` field to any page's frontmatter. See [[EncryptedPages]] for full setup instructions.
---
title: EncryptedPages
description: Password-protected encrypted pages with shadow content index.
tags:
- plugin/transformer
- plugin/emitter
image: "#FF1493"
new-in-v5: true
repository: "[quartz-community/encrypted-pages](https://github.com/quartz-community/encrypted-pages)"
enabled: true
required: false
---
Password-protected encrypted pages. Encrypts page content at build time using AES-256-GCM and decrypts client-side with the Web Crypto API. Passwords are set per-page via frontmatter. A companion emitter writes an encrypted shadow content index so unlisted encrypted pages can be dynamically revealed in graph, explorer, and search after a successful decryption โ without ever leaking their metadata to visitors who do not hold the password.
> [!example] Live demo
> Try it yourself: [[EncryptedPages Demo]]. The password is `quartz`.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
## Usage
Add a `password` field to any page's frontmatter to encrypt it:
```yaml
---
title: My Secret Page
password: mysecretpassword
---
```
The page content will be encrypted at build time. Visitors must enter the correct password to view the content.
Successful passwords are cached in the browser's session storage and automatically tried on other encrypted pages for convenience.
### Hiding encrypted pages from discovery surfaces
By default, encrypted pages still appear in the graph, explorer, search, RSS, sitemap, and backlinks โ visitors can see the page exists and its title, but cannot read the content without the password.
To hide an encrypted page entirely until a visitor successfully decrypts it, set `unlisted: true` in its frontmatter:
```yaml
---
title: My Secret Page
password: mysecretpassword
unlisted: true
---
```
An unlisted page:
- Is **absent** from `contentIndex.json`, `sitemap.xml`, the RSS feed, backlinks, recent notes, folder listings, tag listings, bases views, graph, explorer, and search.
- Is still emitted as HTML, so it remains accessible by direct URL.
- Has its metadata (slug, title, links, tags) written to a separate `static/encryptedContentIndex.json` file, encrypted with the page's own password.
- Is dynamically re-added to the in-memory content index when a visitor successfully decrypts it, so graph, explorer, and search reflect it for the rest of the browser session. Server-rendered listings โ backlinks, recent notes, tag pages, folder listings, and [[BasesPage|bases views]] โ remain statically hidden even after decryption because they are baked as HTML at build time.
To make this the default for every encrypted page on your site, set `unlistWhenEncrypted: true` in the plugin options. Individual pages can then opt back in with `unlisted: false`.
> [!note]
> The `unlisted: true` frontmatter field above only takes effect for encrypted pages when this plugin is installed. If you also want `unlisted: true` to work on **non-encrypted** pages across your site, install [[UnlistedPages]] alongside this one. The two plugins compose cleanly โ when both are enabled, `unlisted: true` hides any page, encrypted or not, from every discovery surface that respects the `file.data.unlisted` convention.
### Permanently hiding encrypted pages (`stealth`)
By default, an `unlisted: true` encrypted page is _revealed_ in graph, explorer, and search after a visitor successfully decrypts it. This is usually what you want: the user just proved they know the password, so showing them the page in the sidebar makes sense for the rest of their session.
If you instead want a page that stays permanently invisible โ accessible only by direct URL, even to users who have successfully decrypted other pages on the same site โ set `stealth: true` in its frontmatter:
```yaml
---
title: Deep Secret
password: mysecretpassword
stealth: true
---
```
A stealth page:
- Is **absent** from every discovery surface, same as any `unlisted` page.
- Has **no entry** in the shadow content index (`encryptedContentIndex.json`). The plugin deliberately skips stealth pages when building the shadow index.
- Stays hidden even after the visitor enters the correct password. Since there is no shadow-index entry to decrypt, there is nothing to patch into the in-memory content index โ graph, explorer, and search never learn the page exists. Only the decrypted HTML is visible to the user on the page itself.
- The password is still cached in session storage, so re-visiting the same stealth page will auto-unlock it.
`stealth: true` implies `unlisted: true` โ you do not need to set both, and if you write `stealth: true, unlisted: false` the stealth flag wins. On non-encrypted pages `stealth: true` has no effect (there is no shadow index to skip).
Use stealth pages for "secret door" content that should only reach users who already know the exact URL: private notes linked from an external wiki, personal pages you send to specific people, or anything you never want to show up in a site-internal search even to authenticated readers.
## Configuration
This plugin provides a transformer, an emitter, and a component. All options are set on a single config entry and shared between the transformer and the emitter โ Quartz instantiates both automatically.
- `iterations`: PBKDF2 iteration count for key derivation. Higher values are more secure but slower to unlock. Defaults to `600000`.
- `passwordField`: Frontmatter field name that holds the page password. Shared by the transformer and the emitter. Defaults to `"password"`.
- `unlistWhenEncrypted`: If `true`, every encrypted page is marked `unlisted` unless its frontmatter explicitly overrides it. Defaults to `false`.
- `outputPath`: Output path for the shadow content index, relative to Quartz's output directory. Defaults to `"static/encryptedContentIndex.json"`.
### Component options
- `className`: CSS class for the component wrapper. Defaults to `"encrypted-page-wrapper"`.
### Default options
```yaml title="quartz.config.yaml"
- source: github:quartz-community/encrypted-pages
enabled: true
options:
iterations: 600000
passwordField: password
unlistWhenEncrypted: false
outputPath: static/encryptedContentIndex.json
```
> [!warning]
> The `EncryptedPages` transformer replaces the entire HAST tree of an encrypted page with an opaque ciphertext container. Any transformer that needs to read the real HTML โ in particular [[CrawlLinks]], which populates the links used by backlinks and the shadow content index โ must run **before** `EncryptedPages`. Use the `order` field in `quartz.config.yaml` to control this.
## Security
- Content is encrypted with AES-256-GCM using PBKDF2 SHA-256 key derivation.
- Plaintext is stripped from search indices, RSS feeds, and the shadow content index regardless of visibility setting.
- The shadow content index is a flat array of opaque encrypted blobs. An attacker who downloads it learns only the number of unlisted encrypted pages and the PBKDF2 iteration count โ no slugs, titles, or link relationships leak.
- Passwords are set per-page in frontmatter. Avoid committing passwords to public repositories.
- This is client-side encryption of a static site. It protects against casual browsing but not against determined attackers with access to the page source.
## API
- Category: Transformer, Emitter
- Function name: `ExternalPlugin.EncryptedPages()`, `ExternalPlugin.EncryptedContentIndex()`.
- Source: [`quartz-community/encrypted-pages`](https://github.com/quartz-community/encrypted-pages)
- Install: `npx quartz plugin add github:quartz-community/encrypted-pages`
---
title: ExplicitPublish
description: "Only publishes pages explicitly marked with publish: true."
tags:
- plugin/filter
image:
repository: "[quartz-community/explicit-publish](https://github.com/quartz-community/explicit-publish)"
enabled: false
required: false
---
This plugin filters content based on an explicit `publish` flag in the frontmatter, allowing only content that is explicitly marked for publication to pass through. It's the opt-in version of [[RemoveDrafts]]. See [[private pages]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.
## API
- Category: Filter
- Function name: `ExternalPlugin.ExplicitPublish()`.
- Source: [`quartz-community/explicit-publish`](https://github.com/quartz-community/explicit-publish)
- Install: `npx quartz plugin add github:quartz-community/explicit-publish`
---
title: Explorer
description: File tree explorer sidebar.
tags:
- plugin/component
image:
repository: "[quartz-community/explorer](https://github.com/quartz-community/explorer)"
enabled: true
required: false
---
File tree explorer sidebar.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
See [[plugins/Explorer]] for detailed usage information.
## Configuration
This plugin accepts the following configuration options:
**YAML options** (in `quartz.config.yaml`):
- `title`: The title of the explorer. Defaults to `Explorer`.
- `folderClickBehavior`: The behavior when a folder is clicked. Can be `"link"` to navigate or `"collapse"` to toggle. Defaults to `link`.
- `folderDefaultState`: The default state of folders. Can be `"collapsed"` or `"open"`. Defaults to `collapsed`.
- `useSavedState`: Whether to use local storage to save the state of the explorer. Defaults to `true`.
**TS override options** (in `quartz.ts`, for callback functions that can't be expressed in YAML):
- `sortFn`: Custom sort function for ordering files and folders.
- `filterFn`: Custom filter function to exclude specific nodes.
- `mapFn`: Custom map function to transform node properties (e.g. display names).
- `order`: Array controlling the order of operations. Defaults to `["filter", "map", "sort"]`.
### Default options
```yaml title="quartz.config.yaml"
- source: github:quartz-community/explorer
enabled: true
options:
title: Explorer
folderClickBehavior: link
folderDefaultState: collapsed
useSavedState: true
```
### TS override example
```ts title="quartz.ts"
import * as ExternalPlugin from "./.quartz/plugins"
// Must be placed before loadQuartzConfig()
ExternalPlugin.Explorer({
mapFn: (node) => {
node.displayName = node.displayName.toUpperCase()
return node
},
})
```
See [[features/explorer#Advanced customization]] for more examples.
## API
- Category: Component
- Function name: `ExternalPlugin.Explorer()`.
- Source: [`quartz-community/explorer`](https://github.com/quartz-community/explorer)
- Install: `npx quartz plugin add github:quartz-community/explorer`
---
title: Favicon
description: Emits the site favicon.
tags:
- plugin/emitter
image:
repository: "[quartz-community/favicon](https://github.com/quartz-community/favicon)"
enabled: true
required: false
---
This plugin emits a `favicon.ico` into the `public` folder. It creates the favicon from `icon.png` located in the `quartz/static` folder.
The plugin resizes `icon.png` to 48x48px to make it as small as possible.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.
## API
- Category: Emitter
- Function name: `ExternalPlugin.Favicon()`.
- Source: [`quartz-community/favicon`](https://github.com/quartz-community/favicon)
- Install: `npx quartz plugin add github:quartz-community/favicon`
---
title: FolderPage
description: Generates listing pages for folders.
tags:
- plugin/pageType
image:
repository: "[quartz-community/folder-page](https://github.com/quartz-community/folder-page)"
enabled: true
required: false
---
This plugin is a page type plugin that generates index pages for folders, creating a listing page for each folder that contains multiple content files. It uses the `default` [[layout#Page Frames|page frame]] (three-column layout with sidebars). See [[folder and tag listings]] for more information.
Example: [[advanced/|Advanced]]
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
- `showFolderCount`: Whether to display the number of pages in the folder. Defaults to `true`.
- `showSubfolders`: Whether to include pages from subfolders in the listing. Defaults to `true`.
- `sort`: A function of type `(f1: QuartzPluginData, f2: QuartzPluginData) => number{:ts}` used to sort entries. Defaults to sorting by date and tie-breaking on lexographical order. Requires a TS override.
- `prefixFolders`: If `true`, generated folder page titles are prefixed with "Folder: " (e.g. "Folder: notes"). Defaults to `false`.
## API
- Category: Page Type
- Function name: `ExternalPlugin.FolderPage()`.
- Source: [`quartz-community/folder-page`](https://github.com/quartz-community/folder-page)
- Install: `npx quartz plugin add github:quartz-community/folder-page`
---
title: Fonts
description: Fine-grained font control with per-heading support, Google Fonts integration, and theme font discovery.
tags:
- plugin/transformer
- plugin/emitter
image:
repository: "[quartz-community/fonts](https://github.com/quartz-community/fonts)"
enabled: true
required: false
---
This plugin provides fine-grained control over fonts in your Quartz site. It supports per-heading font families, automatic theme font discovery when used with [Quartz Themes](https://github.com/saberzero1/quartz-themes), Google Fonts integration with automatic weight and italic loading, and falls back to Obsidian's default system font stacks.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
## Why use Fonts?
Quartz uses three CSS variables for fonts: `--headerFont`, `--bodyFont`, and `--codeFont`. Obsidian themes use a different system with per-heading variables (`--h1-font` through `--h6-font`), `--font-text`, and `--font-monospace`. These two systems don't bridge correctly, causing heading fonts to not render as themes intend.
Fonts solves this by:
1. Bridging the Obsidian and Quartz font systems
2. Emitting **unlayered** CSS that correctly overrides Quartz's base heading styles
3. Providing per-heading font control that neither system offers alone
4. Optionally loading fonts from Google Fonts with fine-grained weight and italic control
## Configuration
Font options accept either a CSS font-family string or an object with Google Fonts loading control:
```yaml
# String form
body: '"Inter", sans-serif'
# Object form (for Google Fonts weight/italic control)
body:
name: Inter
weights: [400, 600, 700]
includeItalic: true
```
This plugin accepts the following configuration options:
| Option | Type | Default | Description |
| --------------- | ------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `title` | `FontSpecification` | `header` value | Font family for the site title. |
| `body` | `FontSpecification` | Obsidian default | Font family for body text. |
| `header` | `FontSpecification` | Obsidian default | Default font family for all headings (h1-h6). |
| `code` | `FontSpecification` | Obsidian default | Font family for code and monospace elements. |
| `interface` | `FontSpecification` | Obsidian default | Font family for UI elements. |
| `h1` โ `h6` | `FontSpecification` | `header` value | Per-heading font family overrides. |
| `useThemeFonts` | `boolean` | `true` | Use fonts from [Quartz Themes](https://github.com/saberzero1/quartz-themes) as defaults when it is installed. |
| `fontOrigin` | `string` | `"googleFonts"` | `"googleFonts"` to load from Google Fonts CDN, `"selfHosted"` to download and serve locally, `"local"` for no loading. |
### Default options
```yaml title="quartz.config.yaml"
- source: github:quartz-community/fonts
enabled: true
options:
useThemeFonts: true
fontOrigin: googleFonts
```
### Font resolution
Fonts are resolved using a priority chain:
```
User config (plugin options)
โ Theme fonts (from Quartz Themes, if installed)
โ Obsidian defaults (system font stacks)
```
For individual headings:
```
h1 option โ header option โ theme --h1-font โ theme font โ Obsidian default
```
For the site title:
```
title option โ header option โ theme font โ Obsidian default
```
## Usage with Quartz Themes
When [Quartz Themes](https://github.com/saberzero1/quartz-themes) is installed and enabled, Fonts automatically discovers the theme's font metadata and uses it as defaults. Any options you explicitly set in Fonts will override the theme fonts.
Fonts must run **after** Quartz Themes. This is handled automatically by plugin ordering (Quartz Themes = 10, Fonts = 60).
> [!warning]
> If Quartz Themes is enabled but hasn't run yet when Fonts executes, you'll see a warning in the console. Make sure Quartz Themes has a lower `defaultOrder` than Fonts.
## Usage without Quartz Themes
Fonts works standalone. Without a theme, it falls back to Obsidian's default system font stacks. You can set fonts explicitly via the plugin options.
## Examples
```yaml title="quartz.config.yaml"
# Use theme fonts automatically (default behavior)
- source: github:quartz-community/fonts
enabled: true
# Override just the heading font
- source: github:quartz-community/fonts
enabled: true
options:
header: '"Playfair Display", serif'
# Full control with per-heading fonts
- source: github:quartz-community/fonts
enabled: true
options:
body: '"Inter", sans-serif'
header: '"Playfair Display", serif'
code: '"JetBrains Mono", monospace'
h1: '"Playfair Display", serif'
h2: '"Lora", serif'
# Load from Google Fonts automatically
- source: github:quartz-community/fonts
enabled: true
options:
fontOrigin: googleFonts
body: Inter
header: Playfair Display
code: JetBrains Mono
# Google Fonts with weight/italic control
- source: github:quartz-community/fonts
enabled: true
options:
fontOrigin: googleFonts
body:
name: Inter
weights: [400, 600, 700]
includeItalic: true
header:
name: Playfair Display
weights: [400, 700]
code:
name: JetBrains Mono
weights: [400]
# Custom title font (separate from header)
- source: github:quartz-community/fonts
enabled: true
options:
fontOrigin: googleFonts
title: Abril Fatface
header: Playfair Display
body: Inter
code: JetBrains Mono
# Self-hosted fonts (downloaded at build time, no external requests)
- source: github:quartz-community/fonts
enabled: true
options:
fontOrigin: selfHosted
body: Inter
header: Playfair Display
code: JetBrains Mono
# Ignore theme fonts entirely
- source: github:quartz-community/fonts
enabled: true
options:
useThemeFonts: false
body: '"Inter", sans-serif'
```
## Self-Hosted Fonts
When `fontOrigin: selfHosted` is set, Fonts downloads fonts from Google Fonts during the build and serves them from your site's `static/fonts/` directory. This makes your site fully self-contained with no external requests to Google at runtime.
At build time, the plugin:
1. Fetches the Google Fonts CSS for your configured fonts
2. Downloads each font file (`.woff2`, `.woff`, etc.)
3. Writes the font files to `static/fonts/` in your build output
4. Generates a `quartz-fonts.css` file with `@font-face` rules pointing to the local files
> [!note]
> Self-hosted fonts require `baseUrl` to be set in your Quartz configuration, since font URLs in the CSS need an absolute path.
```yaml title="quartz.config.yaml"
configuration:
baseUrl: "example.com"
plugins:
- source: github:quartz-community/fonts
enabled: true
options:
fontOrigin: selfHosted
body: Inter
header: Playfair Display
code: JetBrains Mono
```
## Google Fonts Validation
When `fontOrigin: googleFonts` is set and the optional [`google-font-metadata`](https://www.npmjs.com/package/google-font-metadata) package is installed, Fonts validates your font configuration at build time:
- Checks that font family names exist in Google Fonts.
- Warns if requested weights are not available for a font.
- Warns if italic is requested but the font doesn't support it.
Install it to enable validation:
```bash
npm install google-font-metadata
```
Validation warnings are logged to the console but do not block the build.
## API
- Category: Transformer, Emitter
- Function name: `ExternalPlugin.Fonts()` (transformer), `ExternalPlugin.FontsEmitter()` (emitter).
- Source: [`quartz-community/fonts`](https://github.com/quartz-community/fonts)
- Install: `npx quartz plugin add github:quartz-community/fonts`
---
title: Footer
description: Page footer with configurable links.
tags:
- plugin/component
image:
repository: "[quartz-community/footer](https://github.com/quartz-community/footer)"
enabled: true
required: false
---
This plugin renders a footer at the bottom of the page with a "Created with Quartz" message and a set of configurable links.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
## Configuration
This plugin accepts the following configuration options:
- `links`: A map of link labels to their URLs to display in the footer. Defaults to `{}`.
### Default options
```yaml title="quartz.config.yaml"
- source: github:quartz-community/footer
enabled: true
options:
links:
GitHub: https://github.com/jackyzha0/quartz
Discord Community: https://discord.gg/cRFFHYye7t
```
## API
- Category: Component
- Function name: `ExternalPlugin.Footer()`.
- Source: [`quartz-community/footer`](https://github.com/quartz-community/footer)
- Install: `npx quartz plugin add github:quartz-community/footer`
---
title: Frontmatter
aliases:
- note-properties
- Note Properties
description: Parses frontmatter and displays note properties in a collapsible panel.
tags:
- plugin/transformer
- plugin/component
publish: true
enableToc: true
image:
repository: "[quartz-community/note-properties](https://github.com/quartz-community/note-properties)"
enabled: true
required: true
---
This plugin parses the frontmatter of the page using the [gray-matter](https://github.com/jonschlinkert/gray-matter) library and optionally displays selected properties in a collapsible panel. See [[authoring content#Syntax]], [[Obsidian compatibility]] and [[OxHugo compatibility]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
> [!warning]
> This plugin must not be removed, otherwise Quartz will break.
## Configuration
This plugin accepts the following configuration options:
- `delimiters`: the delimiters to use for the frontmatter. Can have one value (e.g. `"---"`) or separate values for opening and closing delimiters (e.g. `["---", "~~~"]`). Defaults to `"---"`.
- `language`: the language to use for parsing the frontmatter. Can be `yaml` (default) or `toml`.
- `includeAll`: include all frontmatter properties in the properties panel. When `false`, only `includedProperties` are shown. Defaults to `false`.
- `includedProperties`: properties to include when `includeAll` is `false`. Defaults to `["description", "tags", "aliases"]`.
- `excludedProperties`: properties to always exclude from display, even when `includeAll` is `true`. Defaults to `[]`.
- `hidePropertiesView`: hide the visual properties panel while still processing frontmatter. Useful if you only need frontmatter parsing without the UI. Defaults to `false`.
### Default options
```yaml title="quartz.config.yaml"
- source: github:quartz-community/note-properties
enabled: true
options:
includeAll: false
includedProperties:
- description
- tags
- aliases
excludedProperties: []
hidePropertiesView: false
delimiters: "---"
language: yaml
```
## Properties panel
When enabled, this plugin renders a collapsible "Properties" panel before the page body. The panel displays selected frontmatter fields in a table with automatic type rendering:
- **Strings** are shown as plain text. [[wikilinks]] and [markdown links](https://example.com) within strings are rendered as clickable links. Wikilink targets are slugified the same way as body-content links (e.g. `[[My Note]]` resolves to `my-note`) and matching is case-insensitive to mirror Obsidian's behavior, so `[[MyNote]]`, `[[mynote]]`, and `[[MYNOTE]]` all point to the same page.
- **Arrays** are rendered as comma-separated lists.
- **Booleans** are rendered as disabled checkboxes.
- **Numbers** are rendered in a monospace font.
- **Objects** are rendered as JSON in a code block.
- **Tags** get special treatment: they are rendered as highlighted links that point to the corresponding tag page.
- **Null/undefined** values are shown as an em-dash (โ).
### Per-note overrides
You can control the properties panel on a per-note basis using frontmatter keys:
- `quartz-properties` (or `quartzProperties`): set to `true` to force-show the panel, or `false` to force-hide it, overriding the global `hidePropertiesView` setting.
- `quartz-properties-collapse` (or `quartzPropertiesCollapse`): set to `true` to start the panel collapsed, or `false` to start it expanded, overriding the default collapse state.
These keys are automatically excluded from the visible properties table.
```yaml title="Example frontmatter"
---
title: My Note
quartz-properties: true
quartz-properties-collapse: false
---
```
## Supported frontmatter
Quartz supports the following frontmatter fields. Where multiple keys are listed, they are aliases โ the first matching key is used.
| Field | Keys | Description |
| ------------------ | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Title | `title` | Page title. Falls back to filename if empty. |
| Description | `description` | Page description for metadata and search. |
| Tags | `tags`, `tag` | Categorization tags. Slugified the same way as file paths: spaces become `-`, `&` becomes `-and-`, `%` becomes `-percent`, and tags are lowercased so that `#MyTag` and `#mytag` resolve to the same tag page (matching Obsidian). |
| Aliases | `aliases`, `alias` | Alternative names for the page, used for link resolution. |
| Permalink | `permalink` | Custom URL slug. Also added to aliases. |
| CSS classes | `cssclasses`, `cssclass` | CSS classes applied to the page body. |
| Social image | `socialImage`, `image`, `cover` | Image used for social media previews. |
| Social description | `socialDescription` | Description used specifically for social media previews. |
| Created date | `created`, `date` | When the note was created. |
| Modified date | `modified`, `lastmod`, `updated`, `last-modified` | When the note was last modified. Falls back to `created` if unset. |
| Published date | `published`, `publishDate`, `date` | When the note was published. |
| Publish | `publish` | Whether the note should be published. |
| Draft | `draft` | Whether the note is a draft. |
| Comments | `comments` | Whether comments are enabled for the note. |
| Language | `lang` | Language code for the note. |
| Enable TOC | `enableToc` | Whether to show the table of contents. |
## API
- Category: Transformer, Component
- Function name: `ExternalPlugin.NoteProperties()`.
- Source: [`quartz-community/note-properties`](https://github.com/quartz-community/note-properties)
- Install: `npx quartz plugin add github:quartz-community/note-properties`
---
title: GitHubFlavoredMarkdown
description: GitHub Flavored Markdown support (tables, task lists, footnotes, strikethrough).
tags:
- plugin/transformer
image:
repository: "[quartz-community/github-flavored-markdown](https://github.com/quartz-community/github-flavored-markdown)"
enabled: true
required: false
---
This plugin enhances Markdown processing to support GitHub Flavored Markdown (GFM) which adds features like autolink literals, footnotes, strikethrough, tables and tasklists.
In addition, this plugin adds optional features for typographic refinement (such as converting straight quotes to curly quotes, dashes to en-dashes/em-dashes, and ellipses) and automatic heading links as a symbol that appears next to the heading on hover.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
- `enableSmartyPants`: When true, enables typographic enhancements. Default is true.
- `linkHeadings`: When true, automatically adds links to headings. Default is true.
## API
- Category: Transformer
- Function name: `ExternalPlugin.GitHubFlavoredMarkdown()`.
- Source: [`quartz-community/github-flavored-markdown`](https://github.com/quartz-community/github-flavored-markdown)
- Install: `npx quartz plugin add github:quartz-community/github-flavored-markdown`
---
title: Graph
description: Interactive link graph visualization.
tags:
- plugin/component
image:
repository: "[quartz-community/graph](https://github.com/quartz-community/graph)"
enabled: true
required: false
---
Interactive graph visualization.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
See [[graph view]] for detailed usage information.
## Configuration
This plugin accepts the following configuration options:
- `localGraph`: Options for the local graph view.
- `globalGraph`: Options for the global graph view.
Both `localGraph` and `globalGraph` accept the following options:
- `drag`: Enable dragging nodes. Defaults to `true`.
- `zoom`: Enable zooming. Defaults to `true`.
- `depth`: The depth of the graph. Defaults to `1` for local and `-1` for global.
- `scale`: The initial scale of the graph. Defaults to `1.1` for local and `0.9` for global.
- `repelForce`: The force that pushes nodes apart. Defaults to `0.5`.
- `centerForce`: The force that pulls nodes to the center. Defaults to `0.3` for local and `0.2` for global.
- `linkDistance`: The distance between linked nodes. Defaults to `30`.
- `fontSize`: The font size of node labels. Defaults to `0.6`.
- `opacityScale`: The scale of node opacity. Defaults to `1`.
- `removeTags`: Tags to exclude from the graph. Defaults to `[]`.
- `showTags`: Whether to show tags in the graph. Defaults to `true`.
- `enableRadial`: Whether to enable radial layout. Defaults to `false` for local and `true` for global.
- `focusOnHover`: Whether to focus on the hovered node. Defaults to `false` for local and `true` for global.
### Default options
```yaml title="quartz.config.yaml"
- source: github:quartz-community/graph
enabled: true
options:
localGraph:
drag: true
zoom: true
depth: 1
scale: 1.1
repelForce: 0.5
centerForce: 0.3
linkDistance: 30
fontSize: 0.6
opacityScale: 1
removeTags: []
showTags: true
focusOnHover: false
enableRadial: false
globalGraph:
drag: true
zoom: true
depth: -1
scale: 0.9
repelForce: 0.5
centerForce: 0.3
linkDistance: 30
fontSize: 0.6
opacityScale: 1
removeTags: []
showTags: true
focusOnHover: true
enableRadial: true
```
## API
- Category: Component
- Function name: `ExternalPlugin.Graph()`.
- Source: [`quartz-community/graph`](https://github.com/quartz-community/graph)
- Install: `npx quartz plugin add github:quartz-community/graph`
---
title: HardLineBreaks
description: Treats single newlines as hard line breaks.
tags:
- plugin/transformer
image: "#ff8000"
repository: "[quartz-community/hard-line-breaks](https://github.com/quartz-community/hard-line-breaks)"
enabled: false
required: false
---
This plugin automatically converts single line breaks in Markdown text into hard line breaks in the HTML output. This plugin is not enabled by default as this doesn't follow the semantics of actual Markdown but you may enable it if you'd like parity with [[Obsidian compatibility|Obsidian]].
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.
## API
- Category: Transformer
- Function name: `ExternalPlugin.HardLineBreaks()`.
- Source: [`quartz-community/hard-line-breaks`](https://github.com/quartz-community/hard-line-breaks)
- Install: `npx quartz plugin add github:quartz-community/hard-line-breaks`
---
title: Plugins
image:
---
Quartz's functionality is provided by a collection of first-party community plugins. Each plugin can be enabled, disabled, and configured via `quartz.config.yaml`. See [[configuration#Plugins|Configuration]] for details on how to manage plugins.
> [!info] Internal vs Community Plugins
> Quartz has two kinds of plugins:
>
> - **Community plugins** are standalone repositories under [`quartz-community`](https://github.com/quartz-community). In TS overrides, they use `ExternalPlugin.X()` (imported from `.quartz/plugins`).
> - **Internal plugins** are built into Quartz core (Assets, Static, ComponentResources, NotFoundPage). In TS overrides, they use `Plugin.X()` (imported from `./quartz/plugins`).
## Plugin types
Quartz plugins fall into several categories:
- **Transformers** process content during the build, e.g. parsing frontmatter, highlighting syntax, or resolving links.
- **Filters** decide which content files to include or exclude from the output.
- **Page Types** generate HTML pages โ one per content file, folder, tag, canvas, or bases view.
- **Components** render UI elements in the page layout (sidebars, headers, footers, etc.).
## First-party plugins
```base
filters:
and:
- file.ext == "md"
- file.inFolder("plugins")
- "!file.name.startsWith('index')"
- "!file.name.contains('Demo')"
- "!file.name.contains('Static')"
- "!file.name.contains('Assets')"
- "!file.name.contains('ComponentResources')"
- "!file.name.contains('NotFoundPage')"
formulas:
category: |
if(file.hasTag("plugin/transformer"), "Transformer",
if(file.hasTag("plugin/filter"), "Filter",
if(file.hasTag("plugin/pageType"), "Page Type",
if(file.hasTag("plugin/emitter"), "Emitter",
if(file.hasTag("plugin/component"), "Component",
"Other")))))
properties:
title:
displayName: Plugin
repository:
displayName: Repository
enabled:
displayName: Enabled
required:
displayName: Required
description:
displayName: Description
views:
- type: table
name: All Plugins
groupBy:
property: formula.category
direction: ASC
order:
- title
- repository
- enabled
- required
- description
sort:
- property: formula.category
direction: ASC
- property: title
direction: ASC
- type: table
name: Transformers
filters:
and:
- file.hasTag("plugin/transformer")
order:
- title
- repository
- enabled
- required
- description
sort:
- property: title
direction: ASC
- type: table
name: Filters
filters:
and:
- file.hasTag("plugin/filter")
order:
- title
- repository
- enabled
- required
- description
sort:
- property: title
direction: ASC
- type: table
name: Page Types
filters:
and:
- file.hasTag("plugin/pageType")
order:
- title
- repository
- enabled
- required
- description
sort:
- property: title
direction: ASC
- type: table
name: Emitters
filters:
and:
- file.hasTag("plugin/emitter")
order:
- title
- repository
- enabled
- required
- description
sort:
- property: title
direction: ASC
- type: table
name: Components
filters:
and:
- file.hasTag("plugin/component")
order:
- title
- repository
- enabled
- required
- description
sort:
- property: title
direction: ASC
```
> [!note] Multi-category plugins
> Some plugins span multiple categories. **TableOfContents** is both a transformer and a component. **EncryptedPages** is a transformer, emitter, and component. They appear in each relevant category above.
---
title: Latex
description: Renders LaTeX math expressions via KaTeX or Typst.
tags:
- plugin/transformer
image:
repository: "[quartz-community/latex](https://github.com/quartz-community/latex)"
enabled: true
required: false
---
This plugin adds LaTeX support to Quartz. See [[features/Latex|Latex]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
- `renderEngine`: the engine to use to render LaTeX equations. Can be `"katex"` for [KaTeX](https://katex.org/), `"mathjax"` for [MathJax](https://www.mathjax.org/) [SVG rendering](https://docs.mathjax.org/en/latest/output/svg.html), or `"typst"` for [Typst](https://typst.app/) (a new way to compose LaTeX equation). Defaults to KaTeX.
- `customMacros`: custom macros for all LaTeX blocks. It takes the form of a key-value pair where the key is a new command name and the value is the expansion of the macro. For example: `{"\\R": "\\mathbb{R}"}`
- `katexOptions`: Additional options passed to the KaTeX renderer. See the [KaTeX docs](https://katex.org/docs/options) for available options.
- `mathJaxOptions`: Additional options passed to the MathJax renderer. See the [MathJax docs](https://docs.mathjax.org/en/latest/options/) for available options.
- `typstOptions`: Additional options passed to the Typst renderer.
## API
- Category: Transformer
- Function name: `ExternalPlugin.Latex()`.
- Source: [`quartz-community/latex`](https://github.com/quartz-community/latex)
- Install: `npx quartz plugin add github:quartz-community/latex`
---
title: NoteProperties
description: Displays frontmatter properties in a collapsible panel.
tags:
- plugin/component
image:
new-in-v5: true
repository: "[quartz-community/note-properties](https://github.com/quartz-community/note-properties)"
enabled: true
required: true
---
The NoteProperties plugin is documented under [[Frontmatter]].
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
## API
- Category: Component
- Function name: `ExternalPlugin.NoteProperties()`.
- Source: [`quartz-community/note-properties`](https://github.com/quartz-community/note-properties)
- Install: `npx quartz plugin add github:quartz-community/note-properties`
---
title: NotFoundPage
tags:
- plugin/pageType
image:
---
This plugin emits a 404 (Not Found) page for broken or non-existent URLs. It uses the `minimal` [[layout#Page Frames|page frame]] (no sidebars, no header or beforeBody chrome โ only content and footer) to present a clean error page.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.
## API
- Category: Page Type
- Function name: `Plugin.NotFoundPage()` (internal plugin).
- Source: [`quartz/plugins/pageTypes/404.ts`](https://github.com/jackyzha0/quartz/blob/v5/quartz/plugins/pageTypes/404.ts)
---
title: ObsidianFlavoredMarkdown
description: Obsidian-specific Markdown extensions (wikilinks, callouts, highlights, tags, embeds).
tags:
- plugin/transformer
image:
repository: "[quartz-community/obsidian-flavored-markdown](https://github.com/quartz-community/obsidian-flavored-markdown)"
enabled: true
required: false
---
This plugin provides support for [[Obsidian compatibility]].
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
- `comments`: If `true` (default), enables parsing of `%%` style Obsidian comment blocks.
- `highlight`: If `true` (default), enables parsing of `==` style highlights within content.
- `wikilinks`:If `true` (default), turns [[wikilinks]] into regular links.
- `callouts`: If `true` (default), adds support for [[callouts|callout]] blocks for emphasizing content.
- `mermaid`: If `true` (default), enables [[Mermaid diagrams|Mermaid diagram]] rendering within Markdown files.
- `parseTags`: If `true` (default), parses and links tags within the content.
- `parseBlockReferences`: If `true` (default), handles block references, linking to specific content blocks.
- `enableInHtmlEmbed`: If `true`, allows embedding of content directly within HTML. Defaults to `false`.
- `enableYouTubeEmbed`: If `true` (default), enables the embedding of YouTube videos and playlists using external image Markdown syntax.
- `enableTweetEmbed`: If `true` (default), enables the embedding of tweets as static blockquotes from Twitter/X URLs.
- `enableVideoEmbed`: If `true` (default), enables the embedding of video files.
- `enableCheckbox`: If `true`, adds support for interactive checkboxes in content, including custom task characters (e.g. `- [?]`, `- [!]`, `- [/]`). Defaults to `false`.
- `enableObsidianUri`: If `true` (default), marks `obsidian://` protocol links with a CSS class and data attribute for custom styling.
> [!note]
> The `disableBrokenWikilinks` option previously lived on this plugin. It has moved to [[CrawlLinks]], which owns link resolution and can honor the configured `markdownLinkResolution` strategy when deciding whether a link is broken. Users upgrading from earlier Quartz v5 betas should move the option from `ObsidianFlavoredMarkdown` to `CrawlLinks`.
> [!warning]
> Don't remove this plugin if you're using [[Obsidian compatibility|Obsidian]] to author the content!
## API
- Category: Transformer
- Function name: `ExternalPlugin.ObsidianFlavoredMarkdown()`.
- Source: [`quartz-community/obsidian-flavored-markdown`](https://github.com/quartz-community/obsidian-flavored-markdown)
- Install: `npx quartz plugin add github:quartz-community/obsidian-flavored-markdown`
---
title: OxHugoFlavoredMarkdown
description: Compatibility for ox-hugo exported Org-mode files.
tags:
- plugin/transformer
image:
repository: "[quartz-community/ox-hugo](https://github.com/quartz-community/ox-hugo)"
enabled: false
required: false
---
This plugin provides support for [ox-hugo](https://github.com/kaushalmodi/ox-hugo) compatibility. See [[OxHugo compatibility]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
- `wikilinks`: If `true` (default), converts Hugo `{{ relref }}` shortcodes to Quartz [[wikilinks]].
- `removePredefinedAnchor`: If `true` (default), strips predefined anchors from headings.
- `removeHugoShortcode`: If `true` (default), removes Hugo shortcode syntax (`{{}}`) from the content.
- `replaceFigureWithMdImg`: If `true` (default), replaces `<figure/>` with `![]()`.
- `replaceOrgLatex`: If `true` (default), converts Org-mode [[features/Latex|Latex]] fragments to Quartz-compatible LaTeX wrapped in `$` (for inline) and `$$` (for block equations).
> [!warning]
> While you can use this together with [[ObsidianFlavoredMarkdown]], it's not recommended because it might mutate the file in unexpected ways. Use with caution.
>
> If you use `toml` frontmatter, make sure to configure the [[Frontmatter]] plugin accordingly. See [[OxHugo compatibility]] for an example.
## API
- Category: Transformer
- Function name: `ExternalPlugin.OxHugoFlavoredMarkdown()`.
- Source: [`quartz-community/ox-hugo`](https://github.com/quartz-community/ox-hugo)
- Install: `npx quartz plugin add github:quartz-community/ox-hugo`
---
title: PageTitle
description: Renders the site title as a home link.
tags:
- plugin/component
image:
repository: "[quartz-community/page-title](https://github.com/quartz-community/page-title)"
enabled: true
required: false
---
This plugin renders the site-wide page title (configured via the `pageTitle` field in [[configuration]]) as a clickable link to the home page. It typically appears in the left sidebar.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options. The displayed title is controlled by the `pageTitle` field in `quartz.config.yaml`.
## API
- Category: Component
- Function name: `ExternalPlugin.PageTitle()`.
- Source: [`quartz-community/page-title`](https://github.com/quartz-community/page-title)
- Install: `npx quartz plugin add github:quartz-community/page-title`
---
title: ReaderMode
description: Distraction-free reading mode toggle.
tags:
- plugin/component
image:
new-in-v5: true
repository: "[quartz-community/reader-mode](https://github.com/quartz-community/reader-mode)"
enabled: true
required: false
---
Distraction-free reading mode.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
See [[reader mode]] for detailed usage information.
## Configuration
This plugin accepts the following configuration options:
- `enabled`: Whether to enable reader mode. Defaults to `true`.
### Default options
```yaml title="quartz.config.yaml"
- source: github:quartz-community/reader-mode
enabled: true
```
## API
- Category: Component
- Function name: `ExternalPlugin.ReaderMode()`.
- Source: [`quartz-community/reader-mode`](https://github.com/quartz-community/reader-mode)
- Install: `npx quartz plugin add github:quartz-community/reader-mode`
---
title: RecentNotes
description: Displays a list of recently modified notes.
tags:
- plugin/component
image:
repository: "[quartz-community/recent-notes](https://github.com/quartz-community/recent-notes)"
enabled: false
required: false
---
Shows recently modified notes.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
See [[recent notes]] for detailed usage information.
## Configuration
This plugin accepts the following configuration options:
- `title`: The title of the recent notes section. Defaults to `Recent notes`.
- `limit`: The maximum number of recent notes to display. Defaults to `3`.
- `showTags`: Whether to display the tags for each note. Defaults to `true`.
- `linkToMore`: A slug to a page that shows more notes. Defaults to `false`.
- `hideTagPages`: Whether to hide tag index pages from the list. Defaults to `false`.
- `hideFolderPages`: Whether to hide folder index pages from the list. Defaults to `false`.
### Default options
```yaml title="quartz.config.yaml"
- source: github:quartz-community/recent-notes
enabled: true
options:
limit: 3
showTags: true
hideTagPages: false
hideFolderPages: false
```
## API
- Category: Component
- Function name: `ExternalPlugin.RecentNotes()`.
- Source: [`quartz-community/recent-notes`](https://github.com/quartz-community/recent-notes)
- Install: `npx quartz plugin add github:quartz-community/recent-notes`
---
title: RemoveDrafts
description: Filters out pages marked as drafts.
tags:
- plugin/filter
image:
repository: "[quartz-community/remove-draft](https://github.com/quartz-community/remove-draft)"
enabled: true
required: false
---
This plugin filters out content from your vault, so that only finalized content is made available. This prevents [[private pages]] from being published. By default, it filters out all pages with `draft: true` in the frontmatter and leaves all other pages intact.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.
## API
- Category: Filter
- Function name: `ExternalPlugin.RemoveDrafts()`.
- Source: [`quartz-community/remove-draft`](https://github.com/quartz-community/remove-draft)
- Install: `npx quartz plugin add github:quartz-community/remove-draft`
---
title: RoamFlavoredMarkdown
description: Compatibility for Roam Research export format.
tags:
- plugin/transformer
image:
repository: "[quartz-community/roam](https://github.com/quartz-community/roam)"
enabled: false
required: false
---
This plugin provides support for [Roam Research](https://roamresearch.com) compatibility. See [[Roam Research compatibility]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
- `orComponent`: If `true` (default), converts Roam `{{ or:ONE|TWO|THREE }}` shortcodes into HTML Dropdown options.
- `TODOComponent`: If `true` (default), converts Roam `{{[[TODO]]}}` shortcodes into HTML check boxes.
- `DONEComponent`: If `true` (default), converts Roam `{{[[DONE]]}}` shortcodes into checked HTML check boxes.
- `videoComponent`: If `true` (default), converts Roam `{{[[video]]:URL}}` shortcodes into embeded HTML video.
- `audioComponent`: If `true` (default), converts Roam `{{[[audio]]:URL}}` shortcodes into embeded HTML audio.
- `pdfComponent`: If `true` (default), converts Roam `{{[[pdf]]:URL}}` shortcodes into embeded HTML PDF viewer.
- `blockquoteComponent`: If `true` (default), converts Roam `{{[[>]]}}` shortcodes into Quartz blockquotes.
- `tableComponent`: If `true` (default), converts Roam table syntax into HTML tables.
- `attributeComponent`: If `true` (default), converts Roam attribute syntax into rendered attributes.
## API
- Category: Transformer
- Function name: `ExternalPlugin.RoamFlavoredMarkdown()`.
- Source: [`quartz-community/roam`](https://github.com/quartz-community/roam)
- Install: `npx quartz plugin add github:quartz-community/roam`
---
title: Search
description: Full-text search with tag filtering and keyboard navigation.
tags:
- plugin/component
image: https://images.unsplash.com/photo-1516382799247-87df95d790b7
repository: "[quartz-community/search](https://github.com/quartz-community/search)"
enabled: true
required: false
---
Full-text search functionality.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
See [[full-text search]] for detailed usage information.
## Configuration
This plugin accepts the following configuration options:
- `enablePreview`: Whether to show a preview of the page content in search results. Defaults to `true`.
- `fieldPriority`: An array specifying the priority order for search fields. Defaults to `["title", "content", "tags"]`.
### Default options
```yaml title="quartz.config.yaml"
- source: github:quartz-community/search
enabled: true
options:
enablePreview: true
fieldPriority:
- title
- content
- tags
```
## API
- Category: Component
- Function name: `ExternalPlugin.Search()`.
- Source: [`quartz-community/search`](https://github.com/quartz-community/search)
- Install: `npx quartz plugin add github:quartz-community/search`
---
title: Spacer
description: Flexible spacer for layout groups.
tags:
- plugin/component
image:
new-in-v5: true
repository: "[quartz-community/spacer](https://github.com/quartz-community/spacer)"
enabled: true
required: false
---
This plugin renders a flexible spacer element that pushes adjacent components apart within a layout group. It uses CSS `flex: 2 1 auto` to fill available space, making it useful for spacing out items in toolbars or sidebars (for example, separating the search bar from the darkmode toggle in the left sidebar toolbar).
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.
## API
- Category: Component
- Function name: `ExternalPlugin.Spacer()`.
- Source: [`quartz-community/spacer`](https://github.com/quartz-community/spacer)
- Install: `npx quartz plugin add github:quartz-community/spacer`
---
title: StackedPages
description: Andy Matuschak-style stacked sliding panes.
tags:
- plugin/component
image:
new-in-v5: true
repository: "[quartz-community/stacked-pages](https://github.com/quartz-community/stacked-pages)"
enabled: true
required: false
---
Andy Matuschak-style stacked pages (sliding panes). Clicking internal links opens pages side by side in a horizontal stack, allowing you to trace your path through your notes. Each pane shows a full page and can be individually scrolled or closed.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
## Usage
Once enabled, clicking any internal link on a page opens the linked page as a new pane to the right instead of navigating away. The URL updates with a `#stacked=slug1,slug2` hash encoding your current stack, so you can share or bookmark a specific trail of pages.
Stacked pages are disabled on mobile by default (below 800px) since horizontal panning doesn't work well on small screens. On mobile, links navigate normally.
### Interactions
- **Click a link**: Opens the target page in a new pane to the right. If the maximum number of panes is reached, the leftmost pane is removed.
- **Close a pane**: Click the ร button in the pane header to remove it from the stack.
- **Collapsed spines**: When panes overflow the viewport, earlier panes collapse to a thin vertical spine showing the page title. Click a spine to bring that pane back into focus.
- **Browser back/forward**: The full stack state is stored in the URL hash and integrated with browser history, so back/forward navigation works as expected.
## Configuration
This plugin accepts the following configuration options:
- `maxTabs`: Maximum number of stacked panes visible at once. Defaults to `8`.
- `mobileBreakpoint`: Viewport width (in pixels) below which stacked pages are disabled and links navigate normally. Defaults to `800`.
- `showSpines`: Whether to show collapsed spine headers when panes overflow the viewport. Defaults to `true`.
- `animateTransitions`: Whether to animate pane open/close transitions. Defaults to `true`.
### Default options
```yaml title="quartz.config.yaml"
- source: github:quartz-community/stacked-pages
enabled: true
layout:
position: afterBody
priority: 50
display: all
options:
maxTabs: 8
mobileBreakpoint: 800
showSpines: true
animateTransitions: true
```
## API
- Category: Component
- Function name: `ExternalPlugin.StackedPages()`.
- Source: [`quartz-community/stacked-pages`](https://github.com/quartz-community/stacked-pages)
- Install: `npx quartz plugin add github:quartz-community/stacked-pages`
---
title: Static
tags:
- plugin/emitter
image:
---
This plugin emits all static resources needed by Quartz. This is used, for example, for fonts and images that need a stable position, such as banners and icons. The plugin respects the `ignorePatterns` in the global [[configuration]].
> [!important]
> This is different from [[Assets]]. The resources from the [[Static]] plugin are located under `quartz/static`, whereas [[Assets]] renders all static resources under `content` and is used for images, videos, audio, etc. that are directly referenced by your markdown content.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.
## API
- Category: Emitter
- Function name: `Plugin.Static()` (internal plugin).
- Source: [`quartz/plugins/emitters/static.ts`](https://github.com/jackyzha0/quartz/blob/v5/quartz/plugins/emitters/static.ts).
---
title: SyntaxHighlighting
description: Syntax highlighting for code blocks.
tags:
- plugin/transformer
image: https://images.unsplash.com/photo-1580569214296-5cf2bffc5ccd
repository: "[quartz-community/syntax-highlighting](https://github.com/quartz-community/syntax-highlighting)"
enabled: true
required: false
---
This plugin is used to add syntax highlighting to code blocks in Quartz. See [[syntax highlighting]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
- `theme`: a separate id of one of the [themes bundled with Shikiji](https://shikiji.netlify.app/themes). One for light mode and one for dark mode. Defaults to `theme: { light: "github-light", dark: "github-dark" }`.
- `keepBackground`: If set to `true`, the background of the Shikiji theme will be used. With `false` (default) the Quartz theme color for background will be used instead.
- `clipboard`: Whether to add a copy-to-clipboard button to code blocks. Defaults to `true`.
- `tokenClassification`: Whether to add semantic token classification CSS classes to code tokens. Defaults to `true`.
In addition, you can further override the colours in the `quartz/styles/syntax.scss` file.
## API
- Category: Transformer
- Function name: `ExternalPlugin.SyntaxHighlighting()`.
- Source: [`quartz-community/syntax-highlighting`](https://github.com/quartz-community/syntax-highlighting)
- Install: `npx quartz plugin add github:quartz-community/syntax-highlighting`
---
title: TableOfContents
description: Generates and renders a table of contents from headings.
tags:
- plugin/transformer
- plugin/component
image: https://images.unsplash.com/photo-1768527338896-3765921e992d
repository: "[quartz-community/table-of-contents](https://github.com/quartz-community/table-of-contents)"
enabled: true
required: false
---
This plugin generates a table of contents (TOC) for Markdown documents. See [[table of contents]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
- `maxDepth`: Limits the depth of headings included in the TOC, ranging from `1` (top level headings only) to `6` (all heading levels). Default is `3`.
- `minEntries`: The minimum number of heading entries required for the TOC to be displayed. Default is `1`.
- `showByDefault`: If `true` (default), the TOC should be displayed by default. Can be overridden by frontmatter settings.
- `collapseByDefault`: If `true`, the TOC will start in a collapsed state. Default is `false`.
- `layout`: The visual layout of the TOC component. Can be `"modern"` or `"legacy"`. Default is `"modern"`.
> [!warning]
> This plugin needs the `Plugin.TableOfContents` component in `quartz.config.yaml` to determine where to display the TOC. Without it, nothing will be displayed. They should always be added or removed together.
## API
- Category: Transformer, Component
- Function name: `ExternalPlugin.TableOfContentsTransformer()`.
- Source: [`quartz-community/table-of-contents`](https://github.com/quartz-community/table-of-contents)
- Install: `npx quartz plugin add github:quartz-community/table-of-contents`
---
title: TagList
description: Renders tags as clickable links.
tags:
- plugin/component
image:
repository: "[quartz-community/tag-list](https://github.com/quartz-community/tag-list)"
enabled: false
required: false
---
This plugin renders the page's tags as a list of clickable links. Each tag links to its corresponding [[TagPage|tag page]], making it easy for readers to browse related content by topic.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.
## API
- Category: Component
- Function name: `ExternalPlugin.TagList()`.
- Source: [`quartz-community/tag-list`](https://github.com/quartz-community/tag-list)
- Install: `npx quartz plugin add github:quartz-community/tag-list`
---
title: TagPage
description: Generates listing pages for tags.
tags:
- plugin/pageType
image:
repository: "[quartz-community/tag-page](https://github.com/quartz-community/tag-page)"
enabled: true
required: false
---
This plugin is a page type plugin that emits dedicated pages for each tag used in the content. It uses the `default` [[layout#Page Frames|page frame]] (three-column layout with sidebars). See [[folder and tag listings]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
- `numPages`: The maximum number of pages to display per tag before showing a "see more" link. Defaults to `10`.
- `sort`: A function of type `(f1: QuartzPluginData, f2: QuartzPluginData) => number{:ts}` used to sort entries. Defaults to sorting by date and tie-breaking on lexographical order. Requires a TS override.
- `prefixTags`: If `true`, generated tag page titles are prefixed with "Tag: " (e.g. "Tag: recipes"). Defaults to `false`.
## API
- Category: Page Type
- Function name: `ExternalPlugin.TagPage()`.
- Source: [`quartz-community/tag-page`](https://github.com/quartz-community/tag-page)
- Install: `npx quartz plugin add github:quartz-community/tag-page`
---
title: UnlistedPages
description: Hides pages from navigation and indexes while still publishing them.
tags:
- plugin/transformer
image:
new-in-v5: true
repository: "[quartz-community/unlisted-pages](https://github.com/quartz-community/unlisted-pages)"
enabled: true
required: false
---
Zero-config transformer that makes `unlisted: true` in a page's frontmatter a first-class way to opt out of every listing surface on your site. The page is still emitted as HTML and remains accessible by direct URL, but is absent from `contentIndex.json`, RSS, sitemap, graph, explorer, search, backlinks, recent notes, folder listings, and tag listings.
> [!note]
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
## Usage
Add an `unlisted` field to any page's frontmatter:
```yaml
---
title: My Draft
unlisted: true
---
```
That's it. Every Quartz v5 plugin that respects the `file.data.unlisted` convention will then hide the page.
## What each plugin does
| Plugin | Behavior when `unlisted: true` |
| -------------- | -------------------------------------------------------------------------- |
| `ContentIndex` | Page absent from `contentIndex.json`, `sitemap.xml`, and the RSS feed. |
| `Search` | Page absent from search results (derived from `contentIndex.json`). |
| `Graph` | Page absent from graph nodes and edges (derived from `contentIndex.json`). |
| `Explorer` | Page absent from the sidebar file tree (derived from `contentIndex.json`). |
| `Backlinks` | Page never appears as a backlink source on other pages. |
| `RecentNotes` | Page absent from the recent notes list. |
| `FolderPage` | Page absent from folder listings and folder discovery. |
| `TagPage` | Page absent from tag discovery and tag listings. |
In every case, the page's HTML is still emitted and accessible by direct URL.
## Configuration
Zero options. Just enable it.
```yaml title="quartz.config.yaml"
- source: github:quartz-community/unlisted-pages
enabled: true
```
## Interaction with [[EncryptedPages]]
The [[EncryptedPages]] plugin also sets `file.data.unlisted` when its `unlistWhenEncrypted: true` option is set or when a page has `unlisted: true` in frontmatter. The two plugins compose cleanly:
- If you install only `UnlistedPages`: any page with `unlisted: true` in frontmatter is hidden from listing surfaces. Encryption is independent.
- If you install only `EncryptedPages`: `unlisted: true` only takes effect on pages that are also encrypted (have a password). Non-encrypted pages with `unlisted: true` are silently ignored.
- If you install both: `unlisted: true` works for every page, encrypted or not. This is the recommended setup for sites that use encrypted pages.
## API
- Category: Transformer
- Function name: `ExternalPlugin.UnlistedPages()`.
- Source: [`quartz-community/unlisted-pages`](https://github.com/quartz-community/unlisted-pages)
- Install: `npx quartz plugin add github:quartz-community/unlisted-pages`
Discover similar high-velocity repositories, agent skills, and OpenAPI specifications across the ecosystem.
Topic hubs, agent specifications, and quick tools