Edu SDKEdu SDK

Study session

Run a timed study session from createStudySession.

Renders a timed agenda from createStudySession(). Pass session.content (StudySessionContent). The component walks blocks, shows a per-block countdown, and mounts the matching material UI from materials (Quiz, Flashcards, StudyGuide, PracticeProblems, or notes).

Generation stays in edu-sdk. This component does not call createStudySession. Persistence of progress is also app-owned — use onBlockComplete / onSessionComplete if you need hooks.

Generated materials may include optional topics; quiz grades may include byTopic. This runner does not display those fields yet. Pass learnerContext at generation time — see Personalization.

Usage

import { createStudySession } from "edu-sdk";
import { StudySession } from "@edu-sdk/react";
import "@edu-sdk/react/styles.css";

const session = await createStudySession({
  model: "google/gemini-3.6-flash",
  content,
  durationMinutes: 45,
  difficulty: "medium",
});

<StudySession
  session={session.content}
  onBlockComplete={(block, index) => {
    // Optional: persist progress
  }}
  onSessionComplete={() => {
    // Optional: mark the session finished
  }}
/>

Props

type StudySessionProps = {
  session: StudySessionContent;
  className?: string;
  classNames?: StudySessionClassNames;
  allowSkip?: boolean; // default true
  autoAdvance?: boolean; // default false
  renderNotes?: (markdown: string) => ReactNode;
  renderQuiz?: (questions: QuizQuestion[]) => ReactNode;
  renderFlashcards?: (flashcards: Flashcard[]) => ReactNode;
  renderPracticeProblems?: (problems: PracticeProblem[]) => ReactNode;
  renderStudyGuide?: (studyGuide: Artifact<StudyGuideContent>) => ReactNode;
  quizProps?: Omit<QuizProps, "questions">;
  flashcardsProps?: Omit<FlashcardsProps, "flashcards">;
  practiceProblemsProps?: Omit<PracticeProblemsProps, "problems">;
  studyGuideProps?: Omit<StudyGuideProps, "studyGuide">;
  onBlockComplete?: (block: StudySessionBlock, index: number) => void;
  onSessionComplete?: () => void;
};
  • allowSkip — when true (default), a Skip control advances without waiting for the timer.
  • autoAdvance — when true, moving to the next block (or finishing) happens when the block timer hits zero. Default is false.
  • renderNotes — optional Markdown renderer for materials.notes. Without it, notes render as plain preformatted text.
  • renderQuiz / renderFlashcards / renderPracticeProblems / renderStudyGuide — replace the default nested material UI for that type. When set, the matching *Props are ignored.
  • quizProps / flashcardsProps / practiceProblemsProps / studyGuideProps — passed through to the default nested component (excluding the data prop, which StudySession supplies). Use for styling or callbacks like onComplete without replacing the UI.
  • onBlockComplete — fires once per block when the learner leaves it (Next / Skip / Finish) or when the timer expires.
  • onSessionComplete — fires once when the last block is finished (or auto-advanced through).

Empty blocks renders nothing.

Customizing nested materials

Style or wire the default quiz without replacing it:

<StudySession
  session={session.content}
  quizProps={{
    className: "my-session-quiz",
    onComplete: (result) => {
      // Persist GradeQuizResult (may include byTopic)
    },
  }}
/>

Or swap in your own UI:

<StudySession
  session={session.content}
  renderQuiz={(questions) => <MyQuiz questions={questions} />}
  renderFlashcards={(cards) => <MyCards cards={cards} />}
/>

classNames

KeyPart
rootRoot container
headerTopic / goals / tips header
topicSession topic
goalsGoals list
goalEach goal item
tipsTips list
tipEach tip item
progressBlock index row
timerCountdown
blockTitleCurrent block title
blockTypeCurrent block type
instructionsFallback instructions
bodyMaterial / instructions body
notesNotes wrapper
controlsButton row
previousButtonPrevious button
nextButtonNext / Finish button
skipButtonSkip button

Example

<StudySession
  session={session.content}
  allowSkip
  className="my-session"
  classNames={{
    topic: "my-topic",
    timer: "my-timer",
  }}
  renderNotes={(markdown) => <Markdown>{markdown}</Markdown>}
  onSessionComplete={() => {
    // App-owned persistence
  }}
/>

For a fully custom runner (own timers / navigation), see Study session flow. See Styling for styles.css and CSS variables.

On this page