Skip to main content
Quartz uses a plugin-based architecture to transform, filter, and emit your content. Plugins are organized into three categories that form a sequential pipeline:
  1. Transformers - Process and transform Markdown content
  2. Filters - Decide which content should be published
  3. Emitters - Generate output files (HTML, assets, indexes, etc.)

Plugin Pipeline

The build process follows this flow:
1

Transformers

Parse frontmatter, transform Markdown syntax, add syntax highlighting, generate table of contents, and process links.
2

Filters

Determine which files should be published based on frontmatter properties like draft: true.
3

Emitters

Generate HTML pages, copy assets, create RSS feeds, sitemaps, and other output files.

Configuration

Plugins are configured in quartz.config.ts:
quartz.config.ts
import { QuartzConfig } from "./quartz/cfg"
import * as Plugin from "./quartz/plugins"

const config: QuartzConfig = {
  plugins: {
    transformers: [
      Plugin.FrontMatter(),
      Plugin.CreatedModifiedDate({
        priority: ["frontmatter", "git", "filesystem"],
      }),
      Plugin.SyntaxHighlighting({
        theme: {
          light: "github-light",
          dark: "github-dark",
        },
        keepBackground: false,
      }),
      Plugin.ObsidianFlavoredMarkdown({ enableInHtmlEmbed: false }),
      Plugin.GitHubFlavoredMarkdown(),
      Plugin.TableOfContents(),
      Plugin.CrawlLinks({ markdownLinkResolution: "shortest" }),
      Plugin.Description(),
      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(),
    ],
  },
}

export default config

Plugin Types

Transformer Plugin Interface

export type QuartzTransformerPluginInstance = {
  name: string
  textTransform?: (ctx: BuildCtx, src: string) => string
  markdownPlugins?: (ctx: BuildCtx) => PluggableList
  htmlPlugins?: (ctx: BuildCtx) => PluggableList
  externalResources?: (ctx: BuildCtx) => Partial<StaticResources>
}
name
string
required
Unique identifier for the plugin
textTransform
function
Transform raw text before Markdown parsing
markdownPlugins
function
Return array of remark plugins to process Markdown AST
htmlPlugins
function
Return array of rehype plugins to process HTML AST
externalResources
function
Inject external CSS/JS resources into pages

Filter Plugin Interface

export type QuartzFilterPluginInstance = {
  name: string
  shouldPublish(ctx: BuildCtx, content: ProcessedContent): boolean
}
name
string
required
Unique identifier for the plugin
shouldPublish
function
required
Return true to publish the content, false to exclude it

Emitter Plugin Interface

export type QuartzEmitterPluginInstance = {
  name: string
  emit: (
    ctx: BuildCtx,
    content: ProcessedContent[],
    resources: StaticResources,
  ) => Promise<FilePath[]> | AsyncGenerator<FilePath>
  partialEmit?: (...) => Promise<FilePath[]> | AsyncGenerator<FilePath> | null
  getQuartzComponents?: (ctx: BuildCtx) => QuartzComponent[]
  externalResources?: (ctx: BuildCtx) => Partial<StaticResources>
}
name
string
required
Unique identifier for the plugin
emit
function
required
Generate output files during full build
partialEmit
function
Generate output files during incremental rebuild (dev mode)
getQuartzComponents
function
Return components used for rendering (optimization)
externalResources
function
Inject external CSS/JS resources into pages

Plugin Order

Plugin order matters! Transformers run sequentially in the order specified.
Best Practices:
  1. FrontMatter should always be first (parses metadata)
  2. Markdown syntax plugins (GFM, OFM) before link processing
  3. CrawlLinks after syntax plugins (needs final link structure)
  4. Description near the end (needs processed content)

Creating Custom Plugins

Custom Transformer Example

plugins/transformers/myPlugin.ts
import { QuartzTransformerPlugin } from "../types"

export interface Options {
  customOption: string
}

const defaultOptions: Options = {
  customOption: "default",
}

export const MyCustomPlugin: QuartzTransformerPlugin<Partial<Options>> = (userOpts) => {
  const opts = { ...defaultOptions, ...userOpts }
  
  return {
    name: "MyCustomPlugin",
    markdownPlugins() {
      return [
        () => {
          return (tree, file) => {
            // Transform the Markdown AST
            // tree is a unist Node
            // file is a VFile
          }
        },
      ]
    },
  }
}

Custom Filter Example

plugins/filters/myFilter.ts
import { QuartzFilterPlugin } from "../types"

export const MyCustomFilter: QuartzFilterPlugin = () => ({
  name: "MyCustomFilter",
  shouldPublish(_ctx, [_tree, vfile]) {
    // Return true to publish, false to exclude
    return vfile.data?.frontmatter?.customFlag !== false
  },
})

Custom Emitter Example

plugins/emitters/myEmitter.ts
import { QuartzEmitterPlugin } from "../types"
import { write } from "./helpers"

export const MyCustomEmitter: QuartzEmitterPlugin = () => {
  return {
    name: "MyCustomEmitter",
    async *emit(ctx, content, resources) {
      for (const [tree, file] of content) {
        const slug = file.data.slug!
        
        yield write({
          ctx,
          content: "<html>...</html>",
          slug,
          ext: ".html",
        })
      }
    },
  }
}

External Resources

Plugins can inject CSS and JavaScript resources:
export const MyPlugin: QuartzTransformerPlugin = () => {
  return {
    name: "MyPlugin",
    externalResources() {
      return {
        css: [
          { content: "https://cdn.example.com/style.css" }
        ],
        js: [
          {
            src: "https://cdn.example.com/script.js",
            loadTime: "afterDOMReady",
            contentType: "external",
          },
        ],
      }
    },
  }
}

Transformers

Process and transform Markdown content

Filters

Control which content gets published

Emitters

Generate output files and assets

See Also

Build docs developers (and LLMs) love