Skip to content

H5P content types

H5P content types (libraries such as H5P.MultiChoice or H5P.InteractiveVideo) are not code you add to ulams. You install them into the H5P service at runtime. The service is api/h5p, a Node program built on Lumi’s @lumieducation/h5p-server. It is licensed GPL-3.0-or-later and runs as a separate container. For the admin screen see H5P libraries.

H5P’s server code is GPL. ulams keeps it in its own process (LICENSING.md, ADR 0003):

  • No GPL or AGPL code is linked into the API or bundled into the admin or the frontends. Those reach the service only over HTTP, the CLI or an iframe with postMessage.
  • Never copy or port code from api/h5p into other folders. ESLint blocks @lumieducation/* imports in the admin and the legacy front, and yarn lint:gpl checks the front.
  • The frontends embed /h5p/embed/play/:id and /h5p/embed/edit/:id and talk to them with the ulams-h5p:* message protocol.
  • The Laravel package api/packages/h5p (MIT) contains no H5P code. It calls the service with an internal token (X-Internal-Token: $H5P_INTERNAL_TOKEN, acting as a system user with every permission) and the tenant host in X-Forwarded-Host. It may read the h5p.contents table but never writes to the h5p schema.

Content types have their own licences, usually MIT, but check each one before you ship content that depends on it.

Way Who How
H5P Hub in the editor users with h5p_library_install / h5p_library_update the content-type selector of the editor lists Hub types; installing is one click
Admin screen the same permissions upload a .h5p library package, restrict, delete, refresh the Hub cache
Content upload callers allowed to install libraries POST /h5p/contents/upload installs every library inside the package
Library package h5p_library_upload or h5p_library_install POST /h5p/libraries with the field file
CLI operators seed in the service container (below)

The Hub is enabled by H5P_HUB_ENABLED (default true). The H5P Content Hub (shared content) is off.

Run it in the service container. It acts as the system user, prints a JSON report and exits with code 2 if any item failed.

Terminal window
docker compose -f api/docker-compose.yml exec h5p node dist/cli/seed.js --help
docker compose -f api/docker-compose.yml exec h5p node dist/cli/seed.js --hub H5P.MultiChoice,H5P.DragQuestion
docker compose -f api/docker-compose.yml exec h5p node dist/cli/seed.js --samples # curated examples
docker compose -f api/docker-compose.yml exec h5p node dist/cli/seed.js --samples multiple-choice,drag-and-drop
docker compose -f api/docker-compose.yml exec h5p node dist/cli/seed.js --list-samples
docker compose -f api/docker-compose.yml exec h5p node dist/cli/seed.js --hub H5P.MultiChoice ./packages/ https://example.org/x.h5p

--out file.json writes the report to a file. In development, corepack yarn workspace api-h5p seed:dev runs the TypeScript source. The samples are defined in api/h5p/src/cli/samples.ts.

PATCH /h5p/libraries/H5P.Foo-1.2
{ "restricted": true }

DELETE /h5p/libraries/:uber (h5p_library_delete) removes a library. GET /h5p/libraries lists them (h5p_library_list).

The per-tenant parts of the Hub (content-type cache, Hub registration, profile cache) are in Redis under h5p:t:<tenantId>:…. The service refreshes the Hub cache for each tenant in the background at start.

  1. Download the H5P core and editor files: corepack yarn workspace api-h5p download:core.
  2. Run it: corepack yarn workspace api-h5p dev.
  3. Test it: corepack yarn workspace api-h5p test. The integration tests (test:integration) run on manual dispatch in CI.

Changes to the service stay inside api/h5p and keep its GPL licence. To give learners something H5P cannot do, write a topic type or integrate an LTI tool instead.