Frequently asked questions¶
Quick answers across onboarding, packaging, and adoption. Detailed runbooks: Troubleshooting hub.
LMS blank page after upload?
Dev preview (npm run dev) uses console telemetry. npm run build succeeding does not mean the LMS upload will work. Before packaging, follow LMS Go-Live (smoke test vs production paths).
What is LessonKit?¶
A React-first framework for building trackable learning experiences and exporting them to SCORM, xAPI, cmi5, or standalone hosting. It is developer tooling—not a visual timeline editor like Storyline.
Do I need to clone the GitHub repo?¶
No, to build a course. Run npx @lessonkit/cli init my-course. Clone only for contributing or monorepo examples.
Which Node.js version do I need?¶
See the Node.js decision table — single source of truth for init, dev/build/package, and monorepo CI.
LessonKit vs H5P vs Storyline¶
Tool |
Best for |
|---|---|
H5P |
LMS content bank, |
Storyline / Captivate |
Visual timeline authoring, traditional e-learning teams |
LessonKit |
React/TypeScript teams, custom UX, one codebase → SCORM/xAPI/cmi5 |
LessonKit ships native React blocks inspired by H5P patterns—it does not embed H5P, import .h5p files, or integrate with H5P Hub. Rebuild activities in React. See Coming from H5P?.
When should I not use LessonKit?¶
You need a WYSIWYG timeline editor with no React development.
Your team cannot maintain a Vite + React app.
You only need a single H5P activity inside an existing LMS content bank (use H5P directly).
Where is my SCORM zip after packaging?¶
Default path (relative to project root):
.lxpack/course/.lxpack/out/course-scorm12.zip
The CLI prints the resolved path. lessonkit.json → paths.outputBaseDir is inside paths.lxpackOutDir, not at the project root. See LMS Go-Live — SCORM output layout.
Why does my LMS not record completion?¶
Set lxpack: { bridge: "auto", allowedParentOrigins: ["https://your-lms.example"] } in courseConfig.ts before packaging. Production builds require the allowlist when the bridge is enabled. The init template defaults to "off". See LXPack bridge.
Why does bridge: "auto" work locally but not in the LMS?¶
Development builds allow bridge forwarding without an allowlist. Production builds require config.lxpack.allowedParentOrigins when bridge is "auto". Add your LMS parent frame origin (scheme + host + port). Discover it from the SCORM preview URL, document.referrer, or browser devtools. Wire onLxpackBridgeMiss in observability. See React troubleshooting.
Why does my packaged course show a blank page or throw on load?¶
Production guard: After npm run build, the SPA runs in production mode inside the LMS. Console-only telemetry sinks and missing proxy URLs are rejected — the app may throw or show a blank screen.
Fix (pick one path):
Smoke test only — Temporarily set
tracking: { enabled: false }andxapi: { enabled: false }incourseConfig.ts, rebuild, and repackage (not for production analytics).Production — Copy
.env.example→.env, setVITE_ANALYTICS_URLandVITE_XAPI_PROXY_URLto backend proxies, rebuild, and repackage.
See LMS Go-Live (smoke vs production decision tree) · Production checklist.
Why did npm run build succeed but my packaged course is blank or throws?¶
npm run build only compiles the Vite bundle — it does not validate production runtime config. When the LMS launches the course, production mode enforces real analytics/xAPI transports (or explicit enabled: false), observability hooks, and bridge allowlists. Dev console sinks are rejected. See Production checklist · Troubleshooting — production build throws · Ship to LMS checklist.
What does lessonkit package --strict do?¶
--strict maps to lxpack strictBuild: packaging fails when the LXPack build reports warning-severity issues (non-fatal validation noise that would otherwise still produce a zip).
Use it in CI or before production handoff when you want warnings treated as errors. It is separate from --strict-parity, which fails on React ↔ manifest ID mismatches and optional parity warnings.
lessonkit package --target scorm12 --strict
See Packaging & CLI · CLI reference.
What is the default passing score for quizzes?¶
In the React SPA, Quiz / assessment plugins use passingScore on the block (default 1.0 = 100% when omitted in many paths).
In the LMS shell and lxpack bridge, omitted passingScore in lessonkit.json assessments also defaults to 1.0 (aligned with SPA since 1.6.x audit fixes).
Factual correctness vs pass threshold: Telemetry may record whether the learner selected the correct answer separately from whether they met the passingScore threshold. Custom plugins should follow the same split. See Telemetry.
Why can’t I package fillInBlanks / hotspot assessments into the LMS shell?¶
Kinds such as fillInBlanks, findHotspot, and findMultipleHotspots are SPA-only — they score in the React app and emit bridge events, but are not injected as LMS shell quizzes. Remove them from lessonkit.json assessments[] for LMS targets, or use injectable kinds (mcq, trueFalse). The CLI prints SPA-only guidance on failure.
How do I keep React and lessonkit.json in sync?¶
Align courseId, lessonId, and every checkId between React props and the manifest. Packaging fails on mismatch. See Keep React IDs in sync.
Is tracking on by default?¶
Yes, when you pass a config object without tracking.enabled: false. Provide a sink, batch sink, or disable tracking explicitly. Same pattern for xAPI (transport or enabled: false).
Where is the API reference?¶
TypeScript types ship on npm (dist/*.d.ts). Browse generated API docs on API reference (TypeDoc for @lessonkit/react, @lessonkit/core, @lessonkit/cli, @lessonkit/xapi, @lessonkit/lxpack, @lessonkit/themes, @lessonkit/accessibility). For component behavior and props, use Components and hooks and Storybook. In your project, IDE “Go to Definition” on @lessonkit/react imports is the fastest path.
How do I upgrade LessonKit?¶
See the Upgrade guide for migration guides by version.
How do I report a security issue?¶
Do not open a public issue. See Security policy.