## 📦 Créer son export SCORM pour LMS

L'onglet **Scorm** de la fenêtre « Publier mon projet » génère un paquet prêt à importer dans votre LMS, dans le standard de votre choix : SCORM 1.2, SCORM 2004, cmi5 ou xAPI (Tin Can). Votre histoire y devient un module de formation suivi : le LMS enregistre le score, la réussite et l'achèvement de chaque apprenant.


[▶️ Vidéo : l'onglet Scorm de la fenêtre Publier](https://celestory-docs-videos.netlify.app/fr/export-plateforme/scorm.html)


### Ce qu'il faut avoir

* Un abonnement **Pro** ou supérieur. Avec un abonnement inférieur, le bouton « Mise à niveau » remplace le bouton « Exporter ».
* Un LMS compatible avec le standard choisi. Pour cmi5 et xAPI, le LMS doit fournir un LRS (voir [Créer son export cmi5 pour LMS](https://chatwoot.fr.nocodespacelab.com/hc/celestorydoc/articles/fr-exports-export_cmi5-e4d08f) et [Créer son export xAPI pour LRS](https://chatwoot.fr.nocodespacelab.com/hc/celestorydoc/articles/fr-exports-export_xapi-7da3f3)).

### Exporter en quatre réglages

Ouvrez la fenêtre Publier, choisissez l'onglet **Scorm**, puis réglez :

1. **Titre du module** : le nom affiché dans le LMS. Laissez vide pour reprendre le nom du projet.
2. **Standard** : **SCORM 1.2** (la compatibilité LMS la plus large), **SCORM 2004** (un suivi de complétion plus fin), **cmi5** ou **xAPI (Tin Can)** (les standards modernes, qui envoient les résultats à un LRS).
3. **Score de réussite (%)** : le score minimum, de 0 à 100 (70 par défaut), que l'apprenant doit atteindre pour que le module soit considéré comme réussi. Il est inscrit dans le paquet pour SCORM 1.2, SCORM 2004 et cmi5.
4. **Marquer le module comme terminé à la fin de l'histoire** : option désactivée par défaut. Quand l'histoire arrive à sa fin, le LMS reçoit le statut « Terminé », sauf si un bloc Envoyer au LMS a déjà envoyé « Réussi », « Échoué » ou « Terminé ». Sans cette option ni bloc, le LMS ne voit jamais le module terminé.

Cliquez ensuite sur **Exporter** puis importez le paquet obtenu dans votre LMS.

### Envoyer le score et la réussite : le bloc Envoyer au LMS

Le score et la progression viennent des blocs [Envoyer au LMS](lien:blocs-celestory/traitement-des-donnees/envoyer-au-lms.md) placés dans votre graphe, quel que soit le standard : vous choisissez où le résultat part (fin d'un quiz, dernière scène...). Ce bloc envoie un score converti en pourcentage et un statut (Réussi, Échoué, Terminé, En cours). Il n'agit que dans un module exporté depuis cet onglet et lancé depuis un LMS : dans l'aperçu et dans les autres exports, il est ignoré sans erreur.

Selon le standard, la note de réussite se comporte ainsi :

* **SCORM 2004** : le LMS compare le score du bloc à la note de réussite de l'export.
* **SCORM 1.2, cmi5 et xAPI** : le statut « Réussi » ou « Échoué » choisi dans le bloc est retenu en premier (certains LMS SCORM 1.2 le recalculent avec la note de passage).

### Ce qui a été testé

Un module de test envoyant un score de 85 % avec le statut « Réussi » a été importé et lancé sur SCORM Cloud dans les quatre standards (SCORM 1.2, SCORM 2004, cmi5 et xAPI) : le LMS a affiché l'achèvement, la réussite et le score de 85 %. En xAPI, les relevés `initialized`, `passed` et `completed` sont bien arrivés dans le LRS de SCORM Cloud.

D'autres LMS n'ont pas été testés. Le paquet ne déclare que sa page d'entrée dans son manifeste : SCORM Cloud l'accepte, mais un LMS plus strict pourrait le refuser. Importez-le d'abord dans un environnement de test avant de le déployer à vos apprenants.

### Ce que le format SCORM ne fait pas

* C'est un format exporté, hébergé par le LMS : il faut le recréer et le réimporter à chaque mise à jour.
* Il ne donne pas un suivi granulaire de l'apprenant. Pour cela, utilisez les analytics de Celestory (vérifiez que l'hébergeur du module autorise l'envoi de statistiques).
* Il ne prend pas en compte les variables (booléennes, numériques, texte...), pourtant très utiles pour créer une simulation. Il faut passer par Voltask pour les récupérer (installation locale possible).

### Tester votre paquet sur SCORM Cloud

Vous pouvez essayer votre paquet sur un site de test comme https://app.cloud.scorm.com/sc/user/Home : importez-le, cliquez sur Launch, puis finissez le module dans le nouvel onglet qui s'ouvre.

![Test d'un zip au format scorm](https://chatwoot.fr.nocodespacelab.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBYXc9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--9a0c4c6ec344c5582d80912501c753e0bad99f1a/capture-decran-2025-07-01-a-14_1mlfvvm.png)

![Téléversez le zip recréé](https://chatwoot.fr.nocodespacelab.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBYTg9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--7e543f31093aecb38805f564863a15ece23c657b/capture-decran-2025-07-01-a-14_gwcpje.png)

![Quand le zip Scorm est téléversé, cliquez sur Launch](https://chatwoot.fr.nocodespacelab.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBYkE9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--c495fbc5339400a93287ad70b3c2aeacbc203a17/capture-decran-2025-07-01-a-14_jdhnxh.png)

![En lançant le test Scorm, un nouvel onglet apparait. Finissez y le module pour qu'il se referme.](https://chatwoot.fr.nocodespacelab.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBYkU9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--ce559868509e16d97176ba261d659bc69e30902d/capture-decran-2025-07-02-a-10_59rn3z.png?cw_image_width=857px)

![Le suivi scorm fonctionne: complétion et pourcentage sont validés](https://chatwoot.fr.nocodespacelab.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBYTQ9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--23d5d84a935c89ed3bc67398d3425bbaf3eaaf51/capture-decran-2025-07-01-a-14_gnwou0.png)

### Méthode manuelle (avancée)

⚠️ Cette méthode fabrique le paquet à la main à partir d'un export Web ou PWA, avec des blocs JavaScript. Elle n'est plus nécessaire avec l'onglet Scorm, qui s'en charge pour vous : ne l'utilisez pas en plus d'un export de l'onglet Scorm, car les blocs ci-dessous remplacent l'API fournie par l'export. Elle reste utile si vous avez besoin d'un manifeste sur mesure.

Vous pouvez vous baser sur le graphe exemple: https://creator.celestory.io/project/phHUew7e6

Seuls les blocs commençant par SCORM sont à rajouter où vous le voulez dans votre graphe.

![Exemple graphe SCORM](https://chatwoot.fr.nocodespacelab.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBYTA9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--81c24db6efe24deee800f3945920a4b0f7e34c68/capture-decran-2025-07-01-a-14_1prjtpy.png)

1. Ajoutez des blocs Javascript pour déclencher le suivi SCORM. Commencez par copier coller chaque contenu des blocs Javascript que vous créez:

**SCORM API**
```
function SCORM_ScanParentsForApi(win)
{
    /*
    Establish an outrageously high maximum number of
    parent windows that we are will to search as a
    safe guard against an infinite loop. This is
    probably not strictly necessary, but different
    browsers can do funny things with undefined objects.
    */
    var MAX_PARENTS_TO_SEARCH = 500;
    var nParentsSearched = 0;

    /*
    Search each parent window until we either:
         -find the API,
         -encounter a window with no parent (parent is null
                or the same as the current window)
         -or, have reached our maximum nesting threshold
    */
    while ( (win.API == null || win.API === undefined) &&
            (win.parent != null) && (win.parent != win) &&
            (nParentsSearched <= MAX_PARENTS_TO_SEARCH)
          )
    {

        nParentsSearched++;
        win = win.parent;
    }

    /*
    If the API doesn't exist in the window we stopped looping on,
    then this will return null.
    */
    return win.API;
}

function SCORM_GetAPI()
{
    var API = null;

    //Search all the parents of the current window if there are any
    if ((window.parent != null) && (window.parent != window))
    {
        API = SCORM_ScanParentsForApi(window.parent);
    }

    /*
    If we didn't find the API in this window's chain of parents,
    then search all the parents of the opener window if there is one
    */
    if ((API == null) && (window.top.opener != null))
    {
        API = SCORM_ScanParentsForApi(window.top.opener);
    }

    return API;
}

window.API = SCORM_GetAPI()
```

**SCORM : Initialize Session + Step 0**
```
const step = 0

//const candidate = celestoryPoints._get("candidate", "")

//const startTime = celestoryPoints._get("date", 0) //YYYY-MM-DDThh:mm:ss.mmmmZ
//const spentTime = new Date() - new Date(start) // float in days ? seconds ?

API.LMSInitialize("")

API.LMSSetValue("cmi.core.lesson_status", "incomplete");
API.LMSSetValue("cmi.core.score.raw", step);   // Enregistre le score de l'utilisateur
API.LMSCommit("");   // Sauvegarde les données
```

**SCORM : Step 1**
```
const step = 70

console.log("raw score to "+step);
API.LMSSetValue("cmi.core.score.raw", step);   // Enregistre le score de l'utilisateur
API.LMSCommit("");   // Sauvegarde les données
```

*Note: Vous pouvez rajouter autant d'étapes que vous le souhaitez en dupliquant le bloc "SCORM : Step 1" et en indiquant le pourcentage atteint.*
 *Il est par défaut de 70%, mais vous pouvez rajouter des étapes intermédiaires. (ex: 10%, 20%, 50%)*

**SCORM : Step 2 + Complete**
```
const step = 100

console.log("raw score to "+step);
API.LMSSetValue("cmi.core.score.raw", step);

console.log("complete course");
API.LMSSetValue("cmi.core.lesson_status", "completed");

API.LMSCommit("");   // Sauvegarde les données
```

**SCORM : Finish Session**
```
console.log("Cours terminé, fenetre fermée");
API.LMSFinish("");   // Termine la session SCORM
```

2. Exportez votre projet au format Web ou PWA

3. Décompresser le ZIP téléchargé (ex: SCORM_1.zip)

4. Créez un dossier dans le dossier décompressé avec en titre *nomdumodulescorm* (ex: module1) où vous déplacez l'ensemble du contenu présent

![Exemple dossier scorm](https://chatwoot.fr.nocodespacelab.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBYmc9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--7d482989be43a3f5e814e566ac865ae35276ac95/exemple-dossier-scorm_1b9yed7.png?cw_image_width=421px)

5. Téléchargez ce fichier XML **imsmanifest.xml** que vous rajouter dans votre dossier parent: 
[▶️ Vidéo](https://drive.google.com/file/d/1T4VRwd0ZUeZIQJzMConNlEseQxFX3DF0/preview)


6. Compressé votre dossier parent SCORM_1 en fichier zip
Voici le lien du fichier zip exemple: 
[▶️ Exemple zip](https://drive.google.com/file/d/15ZpxKdtNX4ZIiCqNQ2rHB4OG9BmY-zGL/preview)
