LESSON.md Bundles
A LESSON.md bundle is a zip of LESSON.md files that Slate’s import dialog turns into a new course in one step. Author the files in any text editor or AI tool, organize them as a flat list or in section folders, drop the zip on the dialog, and you have a course.
The import flow is free on all plans (free accounts share the 5-import lifetime cap with other formats). Bundled media uploads follow the same plan rules as Slate and Rise imports.
Two zip layouts
Section titled “Two zip layouts”Flat: one section, ordered lessons
Section titled “Flat: one section, ordered lessons”Every .md file at the zip root is a lesson. All lessons land in one default section named “Lessons”.
workplace-comm.zip├── 01-welcome.md├── 02-open-with-intent.md├── 03-listen-for-the-request.md├── 04-close-with-a-next-step.md└── media/ └── cover.pngBest for short, single-topic courses.
Foldered: sections from folder names
Section titled “Foldered: sections from folder names”Each subfolder at the zip root is a section. Files inside are lessons in that section.
customer-service.zip├── 01-introduction/│ ├── 01-welcome.md│ └── 02-why-it-matters.md├── 02-during-the-call/│ ├── 01-acknowledge-before-acting.md│ └── 02-handling-uncertainty.md└── 03-wrap-up/ ├── 01-close-the-loop.md └── 02-summary.mdBest when a course has multiple topics or modules.
Layout rules
Section titled “Layout rules”- Numeric prefix sets the order for sections and lessons (
01-,02-, …). Files without a prefix come after the numbered ones, sorted in alphabetical order. - Folder names become section titles.
01-introductionbecomes “Introduction”. The leading01-is dropped, dashes turn into spaces, and the first letter is capitalized. README.mdis ignored at any depth (case-insensitive). A section folder can hold a README explaining its content without the README being treated as a lesson.- Folders are one level deep. A zip with
sections/intro/lesson.md(a lesson nested two folders deep) is rejected with a clear error. Slate sections are flat by design. - Mixed layouts are rejected. A zip with some
.mdfiles at the root and some inside folders is rejected. Pick one structure. .markdownfiles are accepted alongside.md.ASSESSMENT.mdat the zip root becomes the course’s scored assessment. The name is reserved and case-insensitive, and it does not count toward the flat-versus-foldered choice. See Including a scored assessment.
Bundled media
Section titled “Bundled media”Drop an optional media/ folder at the zip root and reference its files from any block with a src property:
::: imagesrc: media/cover.pngalt: Course cover:::On import, the file is uploaded to your Slate media library and the block’s src is rewritten to the resulting URL. The convention works for image, video, audio, and document blocks, plus the imageUrl field on card, flip-card, and carousel blocks.
URL-based media (https://...) continues to work unchanged. You can mix bundled and URL-based media in the same lesson.
The media/ folder name is matched case-insensitively, so Media/ from a case-preserving filesystem is handled the same way.
Including a scored assessment
Section titled “Including a scored assessment”A course bundle can include a scored assessment. Place a file named ASSESSMENT.md at the zip root and Slate adds it as the course’s assessment section, always at the end of the course.
fire-safety.zip├── 01-introduction/│ └── 01-welcome.md├── 02-procedures/│ ├── 01-evacuation.md│ └── 02-extinguishers.md├── ASSESSMENT.md└── media/ └── floor-plan.pngAn ASSESSMENT.md file is a LESSON.md file with a restricted block set and scoring frontmatter (attempt limit, passing score, question order). A bundle may include at most one, and a zip containing only ASSESSMENT.md with no lessons is a valid assessment-only course.
See the ASSESSMENT.md reference for the frontmatter and content rules.
Sample bundles
Section titled “Sample bundles”Two ready-to-import sample zips are available to download:
- Flat bundle - a four-lesson “Workplace Communication Essentials” course.
- Foldered bundle - a three-section “Customer Service Fundamentals” course with two lessons per section.
Download either, drop it on the import dialog, and you have a working course. The samples are tiny (a few KB each), so you can also unzip them and read the source to see how each block type is authored.
The same samples are mirrored on the lesson.md site.
How to import
Section titled “How to import”- From your dashboard, click Import.
- Drop your
.zipfile on the upload area (or click to browse). - Slate detects the bundle, parses each
.mdfile, and shows a preview with the section and lesson tree, total block counts, and any warnings. - Edit the course title (pre-filled from the zip filename) and add a description if you like.
- Click Import Course. Media uploads, the course saves to your library, and you land on the course overview.
Slate automatically adds a title page (the course cover) built from the title and description you entered, so there is nothing to author for it in the zip.
If a file fails to parse (a missing title in frontmatter, an unclosed ::: fence, and so on), it’s skipped with a warning that names the file. If every file in a section fails, the whole section is dropped from the import with a warning. The import only fails outright if there are no parseable lessons in the entire zip.
Plan limits
Section titled “Plan limits”The import flow is free on every plan and counts against the same 5-import lifetime cap on free accounts (shared with Slate and Rise imports).
Media uploads follow the same plan rules as Slate and Rise imports:
| Media type | Free | Standard / Pro |
|---|---|---|
| Images | Uploaded | Uploaded |
| Videos | Skipped (add a link after import) | Uploaded (up to 250 MB each) |
| Documents | Skipped (add a link after import) | Uploaded |
When a video or document is skipped, the block lands in your course with an empty source and a warning. Paste an external link in the editor afterward.
Theme inheritance
Section titled “Theme inheritance”Imported LESSON.md courses inherit your default theme preset, the same way a new blank or AI-generated course does. If you set up brand colors and a logo during onboarding, every LESSON.md bundle you import lands branded. Switch themes from the course’s Theme page afterward like any other course.
Automatic tagging
Section titled “Automatic tagging”Imported LESSON.md courses are tagged lessonmd-import so they sit alongside slate-import and rise-import on the dashboard tag filter. Remove the tag like any other if you prefer.
What’s not supported
Section titled “What’s not supported”- Code blocks. LESSON.md doesn’t include the code block type, because HTML, CSS, and JS don’t fit cleanly into the
key: valueproperty format. Use Slate’s built-in code block editor after import. - Adding lessons to an existing section. Importing a bundle always creates a new course. To add a single LESSON.md lesson to an existing course, use the per-section LESSON.md dialog on the course overview page.
- Manifest files inside the zip. There’s no
COURSE.mdor similar file. A course’s structure is determined entirely by the zip’s folder layout, plus a course title you set in the import dialog.
Related
Section titled “Related”- LESSON.md specification - full block reference and syntax
- ASSESSMENT.md - the scored assessment format
- LESSON.md overview - what the format is, plus the single-lesson quick start
- Importing a Slate or Rise course