quartz/docs/migrating from Quartz 4.md
saberzero1 cdfb1bd85b
docs: rewrite documentation for v5 plugin system
Update feature docs, hosting, CI/CD, getting started, configuration,
layout, architecture, creating components, making plugins, and
migration guide to reflect the v5 community plugin architecture.
2026-02-14 01:35:44 +01:00

257 lines
11 KiB
Markdown

---
title: "Migrating from Quartz 4"
---
## Overview
Quartz 5 introduces a community plugin system that fundamentally changes how plugins and components are managed. Most plugins that were built into Quartz 4 are now standalone community plugins maintained under the [quartz-community](https://github.com/quartz-community) organization. This guide walks through the changes needed to migrate your configuration.
## What Changed
List the key architectural changes:
- **Plugin system**: Plugins are now standalone Git repositories, installed via `npx quartz plugin add`
- **Import pattern**: Community plugins use `ExternalPlugin.X()` (from `.quartz/plugins`) instead of `Plugin.X()` (from `./quartz/plugins`)
- **Layout structure**: `quartz.layout.ts` now uses `defaults` + `byPageType` instead of `sharedPageComponents` + per-layout objects
- **Page Types**: A new plugin category for page rendering (content, folder, tag pages)
- **Component references**: In layout files, community components use `Plugin.X()` (from `.quartz/plugins`) instead of `Component.X()` (from `./quartz/components`)
## Step-by-Step Migration
### 1. Install Community Plugins
Run the following commands to install the default set of community plugins:
```shell
npx quartz plugin add github:quartz-community/explorer
npx quartz plugin add github:quartz-community/graph
npx quartz plugin add github:quartz-community/search
npx quartz plugin add github:quartz-community/backlinks
npx quartz plugin add github:quartz-community/table-of-contents
npx quartz plugin add github:quartz-community/article-title
npx quartz plugin add github:quartz-community/tag-list
npx quartz plugin add github:quartz-community/page-title
npx quartz plugin add github:quartz-community/darkmode
npx quartz plugin add github:quartz-community/content-meta
npx quartz plugin add github:quartz-community/footer
npx quartz plugin add github:quartz-community/content-page
npx quartz plugin add github:quartz-community/folder-page
npx quartz plugin add github:quartz-community/tag-page
npx quartz plugin add github:quartz-community/created-modified-date
npx quartz plugin add github:quartz-community/syntax-highlighting
npx quartz plugin add github:quartz-community/obsidian-flavored-markdown
npx quartz plugin add github:quartz-community/github-flavored-markdown
npx quartz plugin add github:quartz-community/crawl-links
npx quartz plugin add github:quartz-community/description
npx quartz plugin add github:quartz-community/latex
npx quartz plugin add github:quartz-community/remove-draft
npx quartz plugin add github:quartz-community/alias-redirects
npx quartz plugin add github:quartz-community/content-index
npx quartz plugin add github:quartz-community/favicon
npx quartz plugin add github:quartz-community/og-image
npx quartz plugin add github:quartz-community/cname
```
Also install any optional plugins you were using:
```shell
# Only if you used these in v4:
npx quartz plugin add github:quartz-community/comments
npx quartz plugin add github:quartz-community/reader-mode
npx quartz plugin add github:quartz-community/breadcrumbs
npx quartz plugin add github:quartz-community/recent-notes
npx quartz plugin add github:quartz-community/hard-line-breaks
npx quartz plugin add github:quartz-community/citations
npx quartz plugin add github:quartz-community/ox-hugo
npx quartz plugin add github:quartz-community/roam
npx quartz plugin add github:quartz-community/explicit-publish
```
### 2. Update quartz.config.ts
Show before (v4) and after (v5) comparison:
**Before (v4):**
```ts title="quartz.config.ts"
import * as Plugin from "./quartz/plugins"
plugins: {
transformers: [
Plugin.FrontMatter(),
Plugin.CreatedModifiedDate({ priority: ["frontmatter", "git", "filesystem"] }),
Plugin.Latex({ renderEngine: "katex" }),
],
filters: [Plugin.RemoveDrafts()],
emitters: [
Plugin.AliasRedirects(),
Plugin.ComponentResources(),
Plugin.ContentPage(),
Plugin.FolderPage(),
Plugin.TagPage(),
Plugin.ContentIndex({ enableSiteMap: true, enableRSS: true }),
Plugin.Assets(),
Plugin.Static(),
Plugin.NotFoundPage(),
],
}
```
**After (v5):**
```ts title="quartz.config.ts"
import * as Plugin from "./quartz/plugins"
import * as ExternalPlugin from "./.quartz/plugins"
import { layout } from "./quartz.layout"
plugins: {
transformers: [
Plugin.FrontMatter(),
ExternalPlugin.CreatedModifiedDate({ priority: ["frontmatter", "git", "filesystem"] }),
ExternalPlugin.Latex({ renderEngine: "katex" }),
],
filters: [ExternalPlugin.RemoveDrafts()],
emitters: [
ExternalPlugin.AliasRedirects(),
Plugin.ComponentResources(),
ExternalPlugin.ContentIndex({ enableSiteMap: true, enableRSS: true }),
Plugin.Assets(),
Plugin.Static(),
ExternalPlugin.Favicon(),
Plugin.PageTypes.PageTypeDispatcher({
defaults: layout.defaults,
byPageType: layout.byPageType,
}),
ExternalPlugin.CustomOgImages(),
ExternalPlugin.CNAME(),
],
pageTypes: [
ExternalPlugin.ContentPage(),
ExternalPlugin.FolderPage(),
ExternalPlugin.TagPage(),
Plugin.PageTypes.NotFoundPageType(),
],
},
externalPlugins: [
"github:quartz-community/explorer",
"github:quartz-community/graph",
// ... all your community plugins
],
```
Key changes:
- `Plugin.X()` becomes `ExternalPlugin.X()` for community plugins
- `Plugin.FrontMatter()` stays as `Plugin.X()` (it's internal)
- `Plugin.ComponentResources()`, `Plugin.Assets()`, `Plugin.Static()` stay internal
- Page-rendering emitters (`ContentPage`, `FolderPage`, `TagPage`, `NotFoundPage`) move to new `pageTypes` array
- `Plugin.PageTypes.PageTypeDispatcher()` replaces individual page emitters in the `emitters` array
- New `externalPlugins` array lists all community plugin repos
### 3. Update quartz.layout.ts
Show before (v4) and after (v5):
**Before (v4):**
```ts title="quartz.layout.ts"
import * as Component from "./quartz/components"
export const sharedPageComponents: SharedLayout = {
head: Component.Head(),
header: [],
afterBody: [],
footer: Component.Footer({ links: { ... } }),
}
export const defaultContentPageLayout: PageLayout = {
beforeBody: [Component.Breadcrumbs(), Component.ArticleTitle(), Component.ContentMeta(), Component.TagList()],
left: [Component.PageTitle(), Component.Search(), Component.Darkmode(), Component.Explorer()],
right: [Component.Graph(), Component.TableOfContents(), Component.Backlinks()],
}
```
**After (v5):**
```ts title="quartz.layout.ts"
import * as Component from "./quartz/components"
import * as Plugin from "./.quartz/plugins"
export const layout = {
defaults: {
head: Component.Head(),
header: [],
afterBody: [],
footer: Plugin.Footer({ links: { ... } }),
},
byPageType: {
content: {
beforeBody: [Plugin.Breadcrumbs(), Plugin.ArticleTitle(), Plugin.ContentMeta(), Plugin.TagList()],
left: [Plugin.PageTitle(), Plugin.Search(), Plugin.Darkmode(), Plugin.Explorer()],
right: [Plugin.Graph(), Plugin.TableOfContents(), Plugin.Backlinks()],
},
folder: { ... },
tag: { ... },
"404": { beforeBody: [], left: [], right: [] },
},
}
```
Key changes:
- `Component.X()` for community components becomes `Plugin.X()` (imported from `.quartz/plugins`)
- `Component.Head()` and other layout utilities stay as `Component.X()` (from `./quartz/components`)
- `sharedPageComponents` becomes `defaults`
- Per-layout objects become entries in `byPageType`
- Each page type (content, folder, tag, 404) gets its own layout override
### 4. Update CI/CD
Add `npx quartz plugin restore` to your build pipeline, before `npx quartz build`. See [[ci-cd]] for detailed examples.
### 5. Commit and Deploy
```shell
git add quartz.config.ts quartz.layout.ts quartz.lock.json
git commit -m "chore: migrate to Quartz 5 plugin system"
```
## Plugin Reference Table
Show a table mapping v4 Plugin names to v5 equivalents:
| v4 | v5 | Type |
| ----------------------------------- | ------------------------------------------- | --------------------- |
| `Plugin.FrontMatter()` | `Plugin.FrontMatter()` (unchanged) | Internal |
| `Plugin.CreatedModifiedDate()` | `ExternalPlugin.CreatedModifiedDate()` | Community |
| `Plugin.SyntaxHighlighting()` | `ExternalPlugin.SyntaxHighlighting()` | Community |
| `Plugin.ObsidianFlavoredMarkdown()` | `ExternalPlugin.ObsidianFlavoredMarkdown()` | Community |
| `Plugin.GitHubFlavoredMarkdown()` | `ExternalPlugin.GitHubFlavoredMarkdown()` | Community |
| `Plugin.CrawlLinks()` | `ExternalPlugin.CrawlLinks()` | Community |
| `Plugin.Description()` | `ExternalPlugin.Description()` | Community |
| `Plugin.Latex()` | `ExternalPlugin.Latex()` | Community |
| `Plugin.RemoveDrafts()` | `ExternalPlugin.RemoveDrafts()` | Community |
| `Plugin.ContentPage()` | `ExternalPlugin.ContentPage()` | Community (pageTypes) |
| `Plugin.FolderPage()` | `ExternalPlugin.FolderPage()` | Community (pageTypes) |
| `Plugin.TagPage()` | `ExternalPlugin.TagPage()` | Community (pageTypes) |
| `Plugin.NotFoundPage()` | `Plugin.PageTypes.NotFoundPageType()` | Internal (pageTypes) |
| `Plugin.ComponentResources()` | `Plugin.ComponentResources()` (unchanged) | Internal |
| `Plugin.Assets()` | `Plugin.Assets()` (unchanged) | Internal |
| `Plugin.Static()` | `Plugin.Static()` (unchanged) | Internal |
| `Plugin.AliasRedirects()` | `ExternalPlugin.AliasRedirects()` | Community |
| `Plugin.ContentIndex()` | `ExternalPlugin.ContentIndex()` | Community |
And for components in layout:
| v4 Layout | v5 Layout |
| ----------------------------- | ------------------------------------------ |
| `Component.Explorer()` | `Plugin.Explorer()` |
| `Component.Graph()` | `Plugin.Graph()` |
| `Component.Search()` | `Plugin.Search()` |
| `Component.Backlinks()` | `Plugin.Backlinks()` |
| `Component.Darkmode()` | `Plugin.Darkmode()` |
| `Component.Footer()` | `Plugin.Footer()` |
| `Component.TableOfContents()` | `Plugin.TableOfContents()` |
| `Component.Head()` | `Component.Head()` (unchanged, internal) |
| `Component.Spacer()` | `Component.Spacer()` (unchanged, internal) |