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

51 files changed

Lines changed: 2576 additions & 97 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
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)