scope:
- Migrating from Quartz 3/4 to Quartz 5.
- Already on Quartz 5: see Upgrading Quartz.
- New installation: use installation guide.
Before You Start: Save Your Content
risk:
- Switching to
v5replaces working-directory files with the v5 codebase. - Your v4
content/folder disappears until restored. - Back up
content/outside the repo before switching.
# macOS / Linux
cp -r content /tmp/quartz-content
# Windows (PowerShell)
Copy-Item -Recurse content $env:TEMP\quartz-contentYour old branch is preserved
Switching branches does not delete your v4, v3, or Hugo branch. Restore access with
git checkout v4.
Getting the v5 Branch
goal:
- Fetch official
v5. - Create local
v5. - Install dependencies.
- Push
v5to your repository.
# Add the official Quartz repository as a remote called "upstream" (skip if already set)
git remote add upstream https://github.com/jackyzha0/quartz.git
# Fetch the v5 branch from the official repository
git fetch upstream v5
# Create a local v5 branch from the official one
git checkout -b v5 upstream/v5
# Install dependencies
npm i
# Push v5 to your GitHub repository
git push -u origin v5Setting Up Your Site
interactive_setup:
npx quartz createprompts:
template: choosedefault,obsidian,ttrpg, orblog; choose the closest match to your old setup.obsidian: recommended for Obsidian vaults.content strategy: chooseCopy; select your backed-up content folder.
manual_restore:
# macOS / Linux
cp -r /tmp/quartz-content/* content/
# Windows (PowerShell)
Copy-Item -Recurse $env:TEMP\quartz-content\* content\post_create:
- Install plugins referenced in the generated config.
npx quartz plugin install --from-configWhat Changed in v5
core_change:
- Quartz 5 uses a community plugin system.
- Most Quartz 4 built-in plugins now live as standalone repositories under quartz-community.
changes:
- configuration_format:
quartz.config.ts,quartz.layout.ts→quartz.config.yaml - plugin_system: standalone Git repositories installed via
npx quartz plugin add - import_pattern:
ExternalPlugin.X()from.quartz/pluginsreplacesPlugin.X()from./quartz/plugins - layout_structure:
quartz.layout.tsremoved; layout position moved to per-plugin properties inquartz.config.yaml - page_types: new plugin category for content, folder, and tag page rendering
- url_casing: generated URLs now lowercase and hyphenated;
My Notes/Hello World.md→/my-notes/hello-world - v4_url_behavior: preserved original file/folder casing in URLs
URL Casing and SEO
impact:
- v4 URLs containing uppercase letters return 404 after v5 migration unless redirected.
- Search indexing changes because Google treats URLs as case-sensitive.
default_solution:
- AliasRedirects is enabled by default.
- Build detects source paths containing uppercase characters.
- Redirect pages generate at old uppercase URLs.
- SEO signals included:
<link rel="canonical"><meta http-equiv="refresh"><meta name="robots" content="noindex">
- Search engines transfer ranking to new lowercase URLs.
configuration:
- No manual configuration required.
- Case redirects are on by default.
- Disable with
enableCaseRedirects: false.
plugins:
- source: github:quartz-community/alias-redirects
enabled: true
options:
enableCaseRedirects: falseHosting on Netlify?
Netlify lowercases all URLs and issues server-side 301 redirects. Case redirect pages are optional but harmless.
Most users do not need these details
If you used the default Quartz 4 configuration, or only changed settings exposed by
npx quartz create, the setup wizard handles migration. The details below apply to custom plugin configurations.
Plugin Reference Table
v4_to_v5_plugins:
| v4 | v5 | Type |
|---|---|---|
Plugin.FrontMatter() | ExternalPlugin.NoteProperties() | Community |
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 |
component_layout_mapping:
| 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() | Plugin.Spacer() |
Updating Your CI/CD
requirements:
- Install Quartz plugins before building.
- Add dependency and plugin caching where supported.
github_actions_pattern:
- name: Cache dependencies
uses: actions/cache@v5
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Cache Quartz plugins
uses: actions/cache@v5
with:
path: .quartz/plugins
key: ${{ runner.os }}-plugins-${{ hashFiles('quartz.lock.json') }}
restore-keys: |
${{ runner.os }}-plugins-
- run: npm ci
- name: Install Quartz plugins
run: npx quartz plugin install
- name: Build Quartz
run: npx quartz buildcache_behavior:
- Plugin cache key:
quartz.lock.json - Plugins re-download only when lockfile changes.
non_github_ci:
- Cloudflare, Vercel, Netlify, and similar providers should use:
npx quartz plugin install && npx quartz buildprovider_setup:
- See hosting.
Setting Your Default Branch to v5
prerequisite:
- Verify build and deployment success.
steps:
- Open the repository on GitHub.
- Go to
Settings→General. - Under
Default branch, click the switch icon beside the current default branch. - Select
v5. - Click
Update. - Confirm.
effects:
- New clones target
v5. - Pull requests target
v5. - GitHub Pages deployments target
v5. - Old v4 branch remains available.
Update your CI triggers
If your CI workflow targets a specific branch, such as
branches: [v4], update it tov5. See hosting for examples.
Notes for Quartz 3 Users
path:
- Use the same migration flow: get
v5, runnpx quartz create, import content. - Quartz 4 migration is unnecessary.
Key changes from Quartz 3
changes:
- hugo_removed: Quartz now uses Node-based static-site generation; no Go templates or
hugo-obsidian. - full_hot_reload:
npx quartz build --servere-processes all content on every change. - jsx_layouts: layout components use JSX instead of Go templates.
- plugin_system: see Plugins.
Things to update
updates:
- Deploy scripts: see hosting.
- GitHub default branch: set to
v5. - Folder and tag listings:
- folder descriptions:
content/<folder-name>/index.md - tag descriptions:
content/tags/<tag-name>.md
- folder descriptions:
- Custom CSS: update selectors if they depended on Quartz 3 HTML hierarchy or class names.