NPM / STUDIO

Studio with NPM

This guide only covers integrating Studio as a project dependency. It includes the browser part and, when you need it, the server services for saving and importing.

1. Install dependencies

Install Studio and Player in the same project so that the editor can use the Player during learner View.

Terminal
npm install @p2lrn/studio@0.5.0-alpha.11 @p2lrn/player@0.5.0-alpha.11

The Studio and Player versions must be aligned.

2. Register Studio in the app

Import Studio once from client code. Then you can use <p2lrn-studio> in the interface.

JavaScript / TypeScript
import '@p2lrn/studio';
Minimal HTML
<p2lrn-studio></p2lrn-studio>

With this minimal setup you can create a course, open a file or URL, edit, preview and download a new .p2lrn.

3. Open an initial course

The attribute src It is optional. Use it when the application already knows which course the editor should open.

HTML
<p2lrn-studio src="/courses/course.p2lrn"></p2lrn-studio>

The attribute src It is optional. If you do not define it, the user can create a new course from the interface.

4. Generate server routes

After installing Studio, run the setup once within your project. You don't have to write the Save, Reader and Import paths one by one.

Terminal
npx p2lrn-studio setup

The command locates the root of the project, detects the technology and materializes the three operations: /api/p2lrn/studio/save, /api/p2lrn/studio/read and /api/p2lrn/studio/import. Also create the courses folder.

Reader is already part of the Toolkit installed with Studio.

In JavaScript/TypeScript backends routes directly call @p2lrn/studio/server. In PHP, Python, Ruby, .NET, Java, Go, and Rust, setup generates the framework handler and a local Node bridge that runs Reader and import. Another server is not created or raised.

Important before enabling these routes for real users: security depends on your own website.

p2lrn-studio setup creates Save, Reader, and Import, but does not automatically add user authentication or permissions. On your application server you must check who requests each operation and if they have permission to edit that course or center, as well as apply CSRF when using cookies, size limits and authorized storage destinations. These checks must be done before invoking the P2LRN helpers. Consult the integration and security guide. The generated example does not replace your application's permissions system.

5. Tell Studio the generated routes

These attributes only tell the component where the routes that setup has already created are. They do not replace the creation of the backend files.

HTML
<p2lrn-studio
  src="/courses/course.p2lrn"
  save-endpoint="/api/p2lrn/studio/save"
  reader-endpoint="/api/p2lrn/studio/read"
  import-endpoint="/api/p2lrn/studio/import"
  course-path="course">
</p2lrn-studio>
save-endpoint

Generated path to save the exported package.

reader-endpoint

Generated path that Reader uses to analyze documents.

import-endpoint

Generated path to convert external educational packages to P2LRN.

course-path

Logical save path. The default value is course.

6. Why you need to know technology

Studio uses the same three operations in all cases, but each backend declares its routes differently. Detection is used to generate the correct files for that project.

Next.js

Create routes within app/api/....

Nest

Create a controller inside the structure src/.

Laravel / Symfony

Prepares controllers and, where applicable, route definition.

Django / FastAPI / Flask

Prepare views, routers or blueprints compatible with each environment.

Go / Rust / Spring / ASP.NET

Generates the handler, controller or endpoint in the format expected by the project.

See all recognized technologies

Next.js, Express, Nest, Fastify, Hono, SvelteKit, Nuxt, Astro, Remix, React Router, Node.js, PHP, Laravel, Symfony, Django, FastAPI, Flask, Rails, ASP.NET, Spring, Go, Rust and a generic integration.

7. Server auxiliary functions

If your server uses JavaScript or TypeScript, the package exposes helper functions to implement save, reader, and import operations.

JavaScript / TypeScript
import {
  handleP2LRNStudioSave,
  handleP2LRNStudioReader,
  handleP2LRNStudioExternalImport,
} from '@p2lrn/studio/server';

Protect these routes with your application's authentication and authorization. The browser should not be able to freely decide server write paths.

8. Component API

createCourse(options)

Create a new course. options also admits author, createdAt, license and copyrightHolder.

openFile(file) / openUrl(url)

They open a local or remote package.

setMode('edit' | 'preview')

Switch between editing and learner View.

addUnit() / addLesson() / addContent()

They add structure and content.

resourceLibrary

Optional property. Assign an object with list() and get(digest) to enable the shared library.

materializeSharedResource(activityId)

Converts a digest-pinned reference to an embedded fallback using the bytes of the connected library.

download() / saveCourse()

Download or send the package to the configured save endpoint.

exportOfflineAssignment() / downloadOfflineAssignment()

They generate the self-reproducing delivery of Windows or portable ZIP.

reviewOfflineResult(file)

Validate and present a .p2lrn-result returned by the learner.

JavaScript / TypeScript · library
const studio = document.querySelector('p2lrn-studio');
studio.resourceLibrary = resourceLibrary;

9. Events

p2lrn-studio-create

A course has been created.

p2lrn-studio-open

A package has been opened.

p2lrn-studio-download

A package has been downloaded.

p2lrn-studio-save

A server save has completed.

p2lrn-studio-offline-export

An offline delivery has been generated/downloaded; includes format, assignmentId and contentRoot.

p2lrn-studio-offline-review

An offline result has been reviewed; exposes completeness/match status and intent.