Skip to content

COURSE.md

v1.9

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.

Key Values Shown as
title Text The course title (overrides the zip-filename fallback)
description Text A short description on the title page
author Text The author on the title page
duration A whole number of minutes, like 45 The estimated length on the title page (omit to hide the line)
course_id Text The LMS/SCORM course identifier
language An 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.