Skip to content

Commit ef99f07

Browse files
rajat1saxenaRajat
andauthored
SCORM support (#709)
* scorm lessons * Removed embedded iframe in scorm viewer * Removed memory based SCORM caching; Disk based SCORM cache env vars added; Updated docs * added tests for scorm * CodeQL fixes * CodeQL fixes 2 * CodeQL fixes 3 --------- Co-authored-by: Rajat <hi@rajatsaxena.dev>
1 parent 17e6974 commit ef99f07

File tree

51 files changed

+2576
-97
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+2576
-97
lines changed
145 KB
Loading
53.2 KB
Loading
699 KB
Loading
159 KB
Loading
159 KB
Loading
158 KB
Loading

apps/docs/src/pages/en/courses/add-content.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Sections are used to group lessons.
1616

1717
## Lessons
1818

19-
A lesson is a container for the actual learning material. CourseLit supports seven types of lessons, which are as follows.
19+
A lesson is a container for the actual learning material. CourseLit supports multiple types of lessons, which are as follows.
2020

2121
1. Text
2222

@@ -48,6 +48,12 @@ A lesson is a container for the actual learning material. CourseLit supports sev
4848

4949
See the [guide to add a quiz](/en/lessons/add-quiz).
5050

51+
8. SCORM
52+
53+
For sharing SCORM packages.
54+
55+
See the [guide to add a SCORM package](/en/lessons/scorm).
56+
5157
## Steps to add a new lesson
5258

5359
1. From the `Products` section in the dashboard, select your product to open its dashboard.
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
---
2+
title: Add a SCORM package to a course
3+
description: Add a SCORM package to a course
4+
layout: ../../../layouts/MainLayout.astro
5+
---
6+
7+
You can add SCORM packages to your courses in CourseLit. This allows you to import interactive e-learning content created with tools like Articulate Storyline, Rise, Adobe Captivate, iSpring, and more.
8+
9+
> The feature is currently in alpha, which means you may encounter bugs. Please report them in our <a href="https://discord.com/invite/GR4bQsN" target="_blank">Discord</a> group if you run into any.
10+
11+
## What is SCORM?
12+
13+
SCORM (Sharable Content Object Reference Model) is an industry standard for e-learning content. It allows content created in one tool to be used in any SCORM-compliant LMS.
14+
15+
CourseLit supports both **SCORM 1.2** and **SCORM 2004** packages.
16+
17+
## Add a SCORM lesson
18+
19+
1. Go to the `Products` page and click on the course you want to add SCORM content to. Click on `Edit content`.
20+
21+
2. Click on `Add lesson` in any section.
22+
23+
3. On the New Lesson screen, you'll see a row of lesson type cards. Click on the `SCORM` card to select it.
24+
25+
4. Enter a title for your lesson and hit `Save`.
26+
27+
![create SCORM lesson](/assets/lessons/scorm/create.png)
28+
29+
> **Note:** SCORM lessons cannot be previewed. The `Preview` switch will have no effect.
30+
31+
5. A SCORM upload area will appear. Click `Choose File` and select your SCORM package (ZIP file). The maximum file size is **300MB**.
32+
33+
![upload SCORM package](/assets/lessons/scorm/upload.png)
34+
35+
6. Wait for the upload to complete. CourseLit will automatically validate the package and extract the course structure.
36+
37+
![uploaded SCORM package](/assets/lessons/scorm/uploaded.png)
38+
39+
## Replacing a SCORM package
40+
41+
To update an existing SCORM lesson with a new version of the package:
42+
43+
1. Open the SCORM lesson for editing
44+
2. Click the `Replace` button
45+
3. Select the new ZIP file
46+
4. Wait for the upload to complete
47+
48+
## Supported SCORM features
49+
50+
| Feature | SCORM 1.2 | SCORM 2004 |
51+
| --------------------- | --------- | ---------- |
52+
| Progress tracking |||
53+
| Completion status |||
54+
| Resume (suspend data) |||
55+
| Session time |||
56+
| Score reporting |||
57+
58+
## How course completion is calculated
59+
60+
CourseLit uses the data reported by the SCORM package to determine completion. When a learner clicks **Complete and Continue**, CourseLit checks the SCORM status stored in the database.
61+
62+
A lesson is considered complete if **ANY** of the following conditions are met:
63+
64+
1. **Explicit Completion:** The package reports a status of `completed` or `passed`.
65+
66+
- For SCORM 1.2: `cmi.core.lesson_status` is `completed` or `passed`.
67+
- For SCORM 2004: `cmi.completion_status` is `completed` or `cmi.success_status` is `passed`.
68+
69+
2. **Participation Fallback:** If the package does not report a completion status, CourseLit checks for evidence of participation. The lesson will be marked as complete if any of the following fields are present:
70+
- `cmi.suspend_data` (User made progress)
71+
- `cmi.core.session_time` (Time spent is recorded)
72+
- `cmi.core.exit` (Clean exit occurred)
73+
74+
> **Note:** If none of these conditions are met, the learner will see an error message asking them to complete the content first.
75+
76+
## Learner experience
77+
78+
When a learner opens a SCORM lesson:
79+
80+
1. An **Enter** button is displayed
81+
82+
![enter SCORM lesson](/assets/lessons/scorm/learner-enter.png)
83+
84+
2. Clicking the button opens the SCORM content in a popup window
85+
86+
![Popup SCORM lesson](/assets/lessons/scorm/learner-popup.png)
87+
88+
3. Progress is automatically saved as the learner interacts with the content
89+
4. When the learner closes the popup and returns, they can click **Complete and Continue** to proceed
90+
91+
> **Note:** Progress is preserved even if the browser is closed unexpectedly. When the learner returns, they will resume from where they left off.
92+
93+
## Technical notes
94+
95+
### For self-hosted setups
96+
97+
#### Enabling SCORM
98+
99+
SCORM requires disk-based caching to be enabled. Set the `CACHE_DIR` environment variable to enable SCORM support:
100+
101+
| Variable | Description | Required |
102+
| -------------------------- | ------------------------------------------------------- | ------------------- |
103+
| `CACHE_DIR` | Directory path for cache (SCORM uses `CACHE_DIR/scorm`) | **Yes** |
104+
| `SCORM_PACKAGE_SIZE_LIMIT` | Maximum upload size for SCORM packages (in bytes) | No (default: 300MB) |
105+
106+
> **Note:** If `CACHE_DIR` is not set, SCORM uploads will be disabled and the SCORM lesson type will appear grayed out in the lesson creator.
107+
108+
#### Docker Compose Example
109+
110+
```yaml
111+
services:
112+
web:
113+
image: your-app
114+
deploy:
115+
replicas: 3
116+
volumes:
117+
- cache-data:/app/cache
118+
environment:
119+
- CACHE_DIR=/app/cache
120+
121+
volumes:
122+
cache-data:
123+
```
124+
125+
#### Serverless environments
126+
127+
For serverless environments (Vercel, AWS Lambda), you can use `/tmp` as the cache directory:
128+
129+
```
130+
CACHE_DIR=/tmp
131+
```
132+
133+
Note that `/tmp` is ephemeral in serverless - extracted files will be re-extracted on cold starts, but this still works correctly.
134+
135+
## Stuck somewhere?
136+
137+
We are always here for you. Come chat with us in our <a href="https://discord.com/invite/GR4bQsN" target="_blank">Discord</a> channel or send a tweet at <a href="https://twitter.com/courselit" target="_blank">@CourseLit</a>.

apps/web/.env

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,7 @@
2424
# SUPER_ADMIN_EMAIL=your@email.com
2525

2626
# Sequence settings
27-
# SEQUENCE_DELAY_BETWEEN_MAILS = 86400000 # 1 day in milliseconds
27+
# SEQUENCE_DELAY_BETWEEN_MAILS = 86400000 # 1 day in milliseconds
28+
29+
# Cache directory
30+
# CACHE_DIR=/tmp

apps/web/app/(with-contexts)/dashboard/(sidebar)/product/[id]/content/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
Video,
2828
HelpCircle,
2929
ChevronDown,
30+
Droplets,
3031
} from "lucide-react";
3132
import Link from "next/link";
3233
import {
@@ -52,7 +53,6 @@ import {
5253
TooltipProvider,
5354
TooltipTrigger,
5455
} from "@/components/ui/tooltip";
55-
import { Droplets } from "lucide-react";
5656
const { permissions } = UIConstants;
5757

5858
export default function ContentPage() {

0 commit comments

Comments
 (0)