Skip to content

COURSE.md

v1.8

A COURSE.md file sets course-level metadata for a LESSON.md course bundle: the title, description, author, duration, course ID, and language. Added in LESSON.md v1.8, it is optional, and every field inside it is optional.

A course bundle is a zip of lesson files. COURSE.md is a reserved file at the zip root that describes the course as a whole, rather than any one lesson:

  • It carries frontmatter only. Any Markdown below the frontmatter is ignored.
  • The name COURSE.md is reserved and matched case-insensitively.
  • It sits at the zip root alongside section folders without affecting the flat-versus-foldered layout choice.
  • A bundle may include at most one.

Without a COURSE.md, the course title falls back to the zip filename and you fill in the title-page details in the import dialog.

Every field is optional.

KeyValuesShown as
titleTextThe course title (overrides the zip-filename fallback)
descriptionTextA short description on the title page
authorTextThe author on the title page
durationA whole number of minutes, like 45The estimated length on the title page (omit to hide the line)
course_idTextThe LMS/SCORM course identifier
languageAn ISO code (en, fr, pt-BR)The course content language
---
title: Workplace Fire Safety
description: Prevent and respond to workplace fires.
author: Safety Team
duration: 30
course_id: FIRE-101
language: en
---
  • duration is a whole number of minutes. Omit it to hide the duration line on the title page entirely.
  • course_id sets the identifier used in the SCORM manifest, the same value you can set on the Course Overview page.
  • language is an ISO code. Any of Slate’s supported codes works, including regional ones like pt-BR and fr-CA, which are kept exactly as written. A variant Slate doesn’t support maps to its supported base when there is one (en-GB becomes en, es-MX becomes es), which keeps a regional course in the right language; anything unrecognized falls back to en. Friendly names like French are not accepted.

COURSE.md is metadata, not content, so a problem with it never blocks an import. A bad value (a non-numeric duration, an unknown language) produces a warning and is dropped; the rest of the course imports normally. This is different from ASSESSMENT.md, whose errors prevent import.

A zip containing only a COURSE.md and no lessons is not a course and is rejected.

Place COURSE.md at the root of a LESSON.md course zip. Listing it first mirrors the flow of the course: metadata, then lessons, then the assessment.

fire-safety.zip
├── COURSE.md
├── 01-introduction/
│ └── 01-welcome.md
├── 02-procedures/
│ ├── 01-evacuation.md
│ └── 02-extinguishers.md
├── ASSESSMENT.md
└── media/
└── floor-plan.png

On import, Slate builds the course’s title page from the COURSE.md metadata, so there is nothing to edit afterward.