Course structure

When to use

Every course is built from CourseLesson → blocks. Use this shell for all lessons.

  • Course — wraps LessonkitProvider, course title, and courseId.

  • Lesson — sets the active lesson and emits lesson lifecycle telemetry.

  • ProgressTracker — optional chrome that shows completion progress.

In production SPAs, mount one active Lesson at a time (route or step state). The demo shows the minimal happy path with a Quiz inside the lesson.

Requirements

  • courseId, lessonId, and assessment checkId values must be stable for packaging.

  • Pass config on Course for telemetry, xAPI, and LMS bridge (disabled in docs demos).

Try it

Documentation demo

Use the Live demo, React, AI prompt, and Packaging / Manifest tabs below. Embedded demos disable telemetry, xAPI, and the LMS bridge. For production delivery, use the CLI template src/courseConfig.ts and LMS Go-Live.

<Course title="Security fundamentals" courseId="sec-fundamentals" config={courseConfig}>
  <ProgressTracker />
  <Lesson title="Phishing basics" lessonId="phishing-lesson">
    <Scenario blockId="intro">
      <Text>Mount one active Lesson at a time inside Course.</Text>
    </Scenario>
    <Quiz
      checkId="structure-quiz"
      question="Where should scored checks live?"
      choices={["Inside a Lesson, under Course", "Outside Course"]}
      answer="Inside a Lesson, under Course"
    />
  </Lesson>
</Course>

Copy into Cursor, Copilot, or ChatGPT after the vibe coding starter context:

Read lessonkit.json and src/App.tsx before editing.

Ensure the course shell matches this structure:

<Course title="Security fundamentals" courseId="sec-fundamentals" config={courseConfig}>
  <ProgressTracker />
  <Lesson title="Phishing basics" lessonId="phishing-lesson">
    <Scenario blockId="intro">
      <Text>Mount one active Lesson at a time inside Course.</Text>
    </Scenario>
    <Quiz
      checkId="structure-quiz"
      question="Where should scored checks live?"
      choices={["Inside a Lesson, under Course", "Outside Course"]}
      answer="Inside a Lesson, under Course"
    />
  </Lesson>
</Course>

Requirements:
- Import only from @lessonkit/react; use block types from block-catalog.v3.json.
- Keep existing courseId, lessonId, and navigation stable unless I ask to add a lesson.
- After edits, list changed files and what to verify in the browser (lessonkit dev).

Workflow tips: https://lessonkit.readthedocs.io/en/latest/guides/vibe-coding/prompting-and-workflows.html

See also