Skip to main content

Using Quarto

NBIS Workshop

Practical guide to using Quarto with a custom theme
Author

Roy Francis

Published

02-Nov-2026

The custom template is a Quarto website project with HTML reports and Reveal.js presentations.

1 Get started

Quarto 1.8.25 or later is required. To download the starter template, run:

bash
quarto use template royfrancis/specky

The downloaded template does not include _extensions/. Install the required extensions before the first render:

bash
# adds Font Awesome icons
quarto add --no-prompt quarto-ext/fontawesome
# adds a two-logo header to slides
quarto add --no-prompt royfrancis/quarto-revealjs-header
# adds a presenter pointer to slides
quarto add --no-prompt royfrancis/quarto-revealjs-pointer
# adds collapsible code output
quarto add --no-prompt mcanouil/quarto-collapse-output
# adds Bootstrap accordion components
quarto add --no-prompt royfrancis/quarto-accordion
# adds Leaflet maps
quarto add --no-prompt royfrancis/quarto-leaflet
# adds team profile layouts
quarto add --no-prompt royfrancis/quarto-team
# adds Toast UI schedule components
quarto add --no-prompt royfrancis/quarto-toastui

The template command creates a website project that you can modify as needed. After installing the extensions, its key top-level files and directories are:

.
├── 404.md
├── assets/
├── _extensions/
├── home_about.qmd
├── home_coc.qmd
├── home_contents.qmd
├── home_faq.qmd
├── home_precourse.qmd
├── home_schedule.qmd
├── home_syllabus.qmd
├── index.qmd
├── LICENSE
├── schedule.csv
├── _metadata.yml
├── _quarto.yml
├── reports/
└── slides/

2 Preview

Quarto provides a live preview while you edit.

bash
quarto preview
Warning

Preview builds the entire project, so it may fail if any document is incomplete.

Tip

The template sets freeze: false by default. Enabling freeze stores computational output, which can speed up project renders and allow pages to render when the original computation environment or tools are unavailable.

3 Render

A Quarto document can be rendered from the terminal as follows:

bash
# render the full project (freeze works if enabled)
quarto render

# render a specific file (freeze is ignored for single-file renders)
quarto render reports/sample/index.qmd

This generates output in the docs/ directory, as configured by project: output-dir in _quarto.yml. Global output defaults are defined under format in _quarto.yml; a document can override them in its YAML front matter. For example, format: html produces an HTML page, while format: revealjs produces a Reveal.js presentation.

4 Settings

Start by updating _quarto.yml, which contains the project and website settings. See the documentation for Quarto projects and websites.

  • The output directory is set to docs; output-dir: docs
  • Change site-url to your intended destination
  • open-graph: true enables Open Graph metadata, and website: image sets the default image used in social link previews
  • Navigation bar links are set under website: navbar. Add or remove as needed
  • Page footer settings are set under website: page-footer. Check license. Update as needed
  • HTML report settings are under format: html:
    • These are global defaults for all HTML pages and can be overridden in page front matter
    • A custom SCSS theme is defined (assets/css/styles.scss)
    • Table of contents is enabled (toc: true)
    • Sections are automatically numbered (number-sections: true)
    • Long code lines wrap instead of scrolling horizontally (code-overflow: wrap)
    • A default subtitle has been set
    • Last-modified dates are enabled by default (date: last-modified); the home pages override this with date: "". Locally the date is the file modification time; on CI a fresh checkout resets file times, so every page shows the build date
    • Listing cards use the image-placeholder of the listing page (reports/index.qmd, slides/index.qmd) unless a page sets image: in its front matter; image: also becomes the page’s social preview, otherwise website: image is used. A page-level override resolves relative to that document’s own folder, not the project root, so reaching a project asset needs a depth-correct relative path such as ../../assets/images/example.webp
    • Images can be clicked to open in a lightbox (lightbox: auto)
  • Reveal.js presentation settings are under format: revealjs
    • These are global defaults for all Reveal.js presentations and can be overridden in page front matter
    • A custom SCSS theme is defined (assets/css/slides.scss)
    • All items on a slide appear at once (incremental: false), override with .fragment class
    • Use ## to define slides (slide-level: 2)
    • Chalkboard for scribbling is enabled (chalkboard: true)
    • A custom image for each presentation can be set when viewing as listing (image:); the same folder-relative resolution described above for HTML reports applies
    • Set title slide graphic image (hero:)
    • Set title slide background image (title-slide-attributes: data-background-image:)
    • A default subtitle has been set
    • Adjust slide header logo image, size and link (header-logo-*); the header-logo-*-url values are used as-is with no automatic path resolution, so they must be written relative to where the presentation actually renders (../../home_contents.html for this template’s fixed slides/<name>/index.qmd depth)
  • execute settings
    • Executable code cells are evaluated (eval: true), and their source code is displayed (echo: true) by default
    • warnings and messages from chunks are disabled
    • freeze: false disables storage of computational output by default; set it to true or auto if needed
  • Add any arbitrary metadata in _metadata.yml and use it across the project as {{< meta metadata >}}. This is used for map information.
  • Custom filters and extensions
    • Extensions provide additional functionality
    • Filter extensions can be added globally in _quarto.yml or locally in individual qmd files
    • Add quarto version ({{< meta quarto_version >}}) or date/time ({{< meta current_year >}}), enabled through custom lua (assets/custom.lua)
    • Code output folding is enabled through the quarto-collapse-output extension. This is documented here
    • Font Awesome icons are enabled through the fontawesome extension. Use {{< fa icon-name >}} to insert an icon. See the extension documentation
    • Accordions are enabled through the quarto-accordion extension. Define named accordion data under accordion in page front matter and render it with {{< accordion name >}}. See home_faq.qmd and the extension documentation
    • Leaflet maps are enabled through the leaflet extension. Add map information as metadata in _metadata.yml and use the shortcode {{< leaflet mapname >}} to include the map in any qmd file. Leaflet maps are documented here
    • Team profiles are enabled through the team extension. Define profiles under team in page front matter and render a named group with {{< team name >}}. See home_about.qmd and the extension documentation
    • Toast UI schedules are enabled through the toastui extension. Define options under toastui in page front matter and render a named schedule with {{< toastui schedule >}}. In this template, home_schedule.qmd loads schedule.csv; each calendarId in the CSV must match an ID under calendars. See the extension documentation
    • Reveal.js header with logos and pointer extensions are enabled for slides. Press q on slides to show the pointer and q again to hide it
    • Remove an unused extension with quarto remove <extension-id>, for example, quarto remove quarto-ext/fontawesome
  • Add document-specific CSS under format: html: css in page front matter if needed

5 Content

You can now add course content.

The starter template should render completely using Quarto alone. Add R, Python or Julia code chunks as needed.

  • The homepage is index.qmd
  • Files named home_*.qmd are site pages. If you add, remove, or rename one, update website: navbar in _quarto.yml as needed
  • home_schedule.qmd configures a Toast UI schedule that loads schedule.csv. It is recommended that events are 15mins or longer for better display.
  • home_contents.qmd contains Markdown tables with links to the sample report and slides
  • home_about.qmd contains organizer profiles and practical information such as venue and map details
  • home_faq.qmd contains an accordion example with frequently asked questions
  • home_syllabus.qmd shows tab panels
  • home_precourse.qmd contains preparation instructions and a checklist
  • home_coc.qmd contains the NBIS code of conduct
  • Reports and slides are organized in separate folders under reports/ and slides/, respectively
  • reports/index.qmd and slides/index.qmd are listing pages that discover those documents

6 Usage tips and conventions

  • See Quarto’s Markdown basics
  • Use level-2 headings (##) as the highest heading level
  • Use Quarto-style chunk options, such as #| eval: false, rather than `{r eval=FALSE}`
  • .qmd files beginning with _, such as _content.qmd, are child documents and are not rendered alone
  • Include a child document with {{< include _content.qmd >}}. Includes do not work in .ipynb notebooks. Includes are documented here.
  • Dynamic variables can be defined in _variables.yml and used as {{< var variable >}}. Dynamic variables are documented here.
  • Custom metadata can be defined in _metadata.yml and used as {{< meta metadata >}}
  • When using R or Python, declare all libraries in one chunk at the beginning of each document
  • Add a session information chunk at the end of .qmd documents that use code. This helps with reproducibility and debugging. For R, use sessionInfo() or sessioninfo::session_info(). For Python, use import session_info; session_info.show()