Edit

Events

Pass onEvent to a LearnHouseActivity (or to LearnHouseProvider to hear every activity below it). Each event is a plain object with a type.

Step 1loadActivity fetched
Step 2readyFirst content painted
Step 3visibleScrolled into view
Step 4resizeHeight changed
Step 5mediaPlay, pause, progress
Step 6completeReached the end
<LearnHouseActivity
  activityId="activity_…"
  trackCompletion
  onEvent={(event) => {
    if (event.type === 'complete') markLessonDone(event.activityId)
    if (event.type === 'media' && event.action === 'ended') analytics.track('video_finished', { src: event.src })
  }}
/>

All events

typeFieldsWhen
loadactivityThe activity was fetched (or given as a prop)
readyIts first content is on screen, after any block code has loaded
visibleratioThe activity scrolled into view, once
resizewidth, heightIts rendered size changed (a block expanded, an image loaded)
link_clickhref, externalA link inside the activity was clicked
mediaaction (play, pause, ended, progress), media (video, audio), src, currentTime, durationVideo and audio playback. progress fires at most every 5 seconds
completeactivityIdThe end of the activity scrolled into view. Only with trackCompletion
errorerrorLoading or rendering failed
analyticsname, plus the block's own fieldsThe product events LearnHouse's blocks already send

onLoad(activity) and onError(error) are also available as separate props.

Recipes

Mark the lesson complete in LearnHouse

complete fires when the learner reaches the end. Record it with the SDK as the learner, the same as the "Mark as complete" button in LearnHouse:

const lh = useLearnHouseClient() // the provider's @learnhouse/sdk client

<LearnHouseActivity
  activityId={id}
  trackCompletion
  onEvent={(e) => e.type === 'complete' && lh.trail.completeActivity(id)}
/>

Size a modal or an iframe to the content

<LearnHouseActivity
  activityId="activity_…"
  onEvent={(e) => e.type === 'resize' && window.parent.postMessage({ lessonHeight: e.height }, '*')}
/>

Send everything to your analytics

<LearnHouseProvider
  baseUrl="https://learn.your-school.com"
  onEvent={({ type, ...data }) => posthog.capture(`lesson_${type}`, data)}
>
  {children}
</LearnHouseProvider>

When both the provider and the component have onEvent, both are called: the component's for that activity, the provider's for all of them.