npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@teacharium/embed-sdk

v0.2.1

Published

SDK for embedding Teacharium lessons via iframe

Readme

Teacharium Embed SDK

A lightweight JavaScript SDK for embedding Teacharium lessons into any website using secure iframe-based embedding with signed JWT tokens.

Installation

npm install @teacharium/embed-sdk

Or use directly via CDN:

<script src="https://unpkg.com/@teacharium/embed-sdk@latest/dist/teacharium-embed-sdk.umd.js"></script>

Quick Start

1. Publish a Lesson Version

In the Teacharium editor, publish a version of your lesson:

  1. Open your lesson in the editor
  2. Go to the Lesson Delivery tab
  3. Click Publish New Version
  4. Expand the published version and click Embed to get the Lesson ID and Version ID

2. Generate a JWT Token (Server-Side)

Generate a signed token from your backend using the Teacharium API. The token must include a lessonId. Optionally include a versionId to pin to a specific published version — if omitted, the most recently published version is used:

const response = await fetch(
  "https://www.teacharium.io/api/public/sign-token",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${publicKey}.${secretKey}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      lessonId: "your-lesson-id",
      versionId: "your-published-version-id", // Optional: omit to use latest version
      learnerId: "learner_anonymous_id",
      userAttributes: {
        userId: "user_12345",
        organizationRole: "student",
      },
      timeout: 3600,
    }),
  },
);

const { token } = await response.json();

Important: Always generate tokens server-side to protect your API credentials. Do not include personally identifiable information (PII) such as email addresses, full names, or phone numbers in learnerId or userAttributes. Use anonymous identifiers instead.

3. Embed the Lesson (Client-Side)

<div id="lesson-container"></div>

<script type="module">
  import { embedLesson } from "@teacharium/embed-sdk";

  const embed = embedLesson({
    container: "#lesson-container",
    token: token, // JWT token from your server
    width: "100%",
    height: "600px",
    onLoad: () => console.log("Lesson loaded"),
    onComplete: (data) => console.log("Lesson completed", data),
    onProgress: (data) => console.log("Progress update", data),
    onError: (error) => console.error("Error", error),
    onEvent: (type, payload) => console.log("Event", type, payload),
  });
</script>

The SDK automatically extracts the lessonId from the JWT token — you do not need to pass it separately.

Using UMD (Browser Global)

<div id="lesson-container"></div>

<script src="https://unpkg.com/@teacharium/embed-sdk@latest/dist/teacharium-embed-sdk.umd.js"></script>
<script>
  const embed = TeachariumEmbed.embedLesson({
    container: "#lesson-container",
    token: "your-jwt-token-here",
    onComplete: (data) => {
      console.log("Lesson completed!", data);
    },
  });
</script>

API Reference

embedLesson(options: EmbedOptions)

Creates and embeds a lesson iframe.

Options:

  • container (required): HTMLElement or CSS selector string for the container
  • token (required): JWT token from /api/public/sign-token (lessonId is automatically extracted)
  • baseUrl (optional): Base URL of your Teacharium instance, default: "https://www.teacharium.io"
  • width (optional): Iframe width, default: "100%"
  • height (optional): Iframe height, default: "600px"
  • className (optional): Additional CSS classes for the iframe
  • autoStart (optional): When true, the lesson starts immediately without showing the start button (default: false)
  • resume (optional): When true, the lesson resumes from where the learner left off. When false, the lesson always starts fresh from the beginning (default: true)
  • onLoad (optional): Callback when lesson iframe loads
  • onComplete (optional): Callback when lesson is completed
  • onProgress (optional): Callback for progress updates
  • onError (optional): Callback for errors
  • onEvent (optional): Callback for all lesson events (see Events)

Returns: TeachariumEmbed instance

TeachariumEmbed Methods

destroy()

Removes the embedded lesson from the page.

embed.destroy();

reload()

Reloads the embedded lesson.

embed.reload();

postMessage(type: string, payload?: unknown)

Send a custom message to the embedded lesson.

embed.postMessage("custom:action", { data: "value" });

getIframe()

Get the iframe element.

const iframe = embed.getIframe();

Events

onEvent (Recommended)

The onEvent callback receives every event emitted by the lesson's internal event system. This is the most flexible way to track lesson activity.

onEvent: (type, payload) => {
  console.log(`Event: ${type}`, payload);
};

Common event types:

| Event Type | Description | Key Payload Fields | | ------------------ | ----------------------------- | -------------------------------------- | | play | User clicked the start button | emittedBy | | lesson_started | Lesson playback began | lessonId, emittedBy | | section_started | Entered a new section | lessonId, sectionId, emittedBy | | step_started | Entered a new step | lessonId, stepId, sectionId | | lesson_completed | User completed the lesson | lessonId, emittedBy | | variable_changed | A lesson variable was updated | variableName, newValue, oldValue | | hideFeedback | Feedback panel was hidden | emittedBy | | showFeedback | Feedback panel was shown | message, variant |

All events include a type field and a timestamp (ISO string).

onLoad

Fired when the lesson iframe has loaded.

onLoad: () => {
  console.log("Lesson is ready");
};

onComplete

Fired when the user completes the lesson.

onComplete: (data) => {
  // data.lessonId - The lesson ID
  // data.completedAt - ISO timestamp
  // data.score - Optional score
  // data.totalSteps - Total number of steps
};

onProgress

Fired when the user progresses through the lesson.

onProgress: (data) => {
  // data.currentStep - Current step number
  // data.totalSteps - Total steps
  // data.sectionIndex - Current section index
  // data.stepIndex - Current step index
};

onError

Fired when an error occurs.

onError: (error) => {
  console.error("Lesson error:", error.message);
};

Security

  • Always generate tokens on your backend, never expose API keys in client-side code
  • Tokens are tied to a specific lesson and organization
  • When versionId is included, the token is pinned to that exact version
  • When versionId is omitted, the most recently published version is served
  • Tokens expire based on the timeout parameter (default 2 hours, max 24 hours)
  • User attributes in tokens cannot be modified without re-signing

Examples

See the Express.js example for a complete working integration.

React Example

import { useEffect, useRef } from "react";
import { embedLesson } from "@teacharium/embed-sdk";

function LessonEmbed({ token }) {
  const containerRef = useRef(null);
  const embedRef = useRef(null);

  useEffect(() => {
    if (containerRef.current && token) {
      embedRef.current = embedLesson({
        container: containerRef.current,
        token: token,
        onComplete: (data) => {
          console.log("Lesson completed!", data);
        },
      });
    }

    return () => {
      if (embedRef.current) {
        embedRef.current.destroy();
      }
    };
  }, [token]);

  return <div ref={containerRef} style={{ width: "100%", height: "600px" }} />;
}

License

MIT