Vue integration
Production integration with ProctoredAssessment: props, slots, lifecycle events, activation, and host responsibilities.
On this page
@a4anthony/proctorkit-vue is the recommended candidate integration. <ProctoredAssessment> is an assessment-runner-neutral orchestration boundary: it resolves the attempt, runs preflight, compiles the selected policy, preserves browser user activation, starts the runtime SDK, handles integrity recovery, and exposes your assessment through slots.
Your assessment runner remains yours. It can be an LMS page, a Vue test engine, or another client application; it does not need to adopt ProctorKit's question, answer, routing, or state-management model.
Install and styles
pnpm add @a4anthony/proctorkit-vueimport "@a4anthony/proctorkit-vue/style.css";Shared form controls
The package exports ProctoringInput, ProctoringSelect, and ProctoringFileUpload for host-owned forms that should match ProctorKit's candidate UI. Candidate intake uses these same components internally, so normal, disabled, focused, and invalid states stay consistent.
<script setup lang="ts">
import { ref } from "vue";
import { ProctoringFileUpload, ProctoringInput, ProctoringSelect } from "@a4anthony/proctorkit-vue";
const candidateId = ref("");
const country
countryOptions
value label
value label
files
script
template
vmodel
id
placeholder
invalid
error
id
prompt
description
accept
multiple
@filesselected
vmodel
id
size
placeholder
options
error
templateProctoringInput accepts modelValue, id, type, size, placeholder, invalid, error, errorId, and disabled; native attributes such as min, max, name, autocomplete, and aria-describedby pass through to the input. It emits update:modelValue and exposes focus() and select(). Pass candidate-facing validation copy through error; the component owns the alert element, danger styling, generated or explicit error id, and aria-describedby connection.
ProctoringSelect accepts modelValue, options, id, size, placeholder, disabled, invalid, error, and errorId. It emits update:modelValue and keeps keyboard navigation, type-ahead, focus management, and listbox ARIA behaviour inside the component. Pass validation copy through error; the component owns the alert element, danger styling, generated or explicit error id, and aria-describedby connection.
ProctoringFileUpload accepts id, accept, multiple, disabled, invalid, error, errorId, prompt, and description; native input attributes pass through to its hidden file input. It emits files-selected with a File[], then clears the native picker value so choosing the same file again still produces an event. It exposes open() and focus(). Pass upload validation copy through error; the component owns the alert element, highlighted dropzone, error id, and accessible description link. Its default slot keeps selected-file rows or supporting help inside the same validation boundary. File validation, selected-file persistence, limits, upload transport, and removal remain host responsibilities.
Production-shaped example
<script setup lang="ts">
import { ProctoredAssessment } from "@a4anthony/proctorkit-vue";
async function saveAndFinish(endSession: () => Promise<void>) {
await saveAnswersToOurBackend();
await endSession();
}
</script>
<template
appid
correlationid
apibaseurl
preset
preflightui
candidate
@sessionerror
template #
proctoringclient
button disabled @click
assessment
button
template
template #ended
completednow
template
templatecorrelationId is your stable exam-attempt id. The wrapper resolves an internal sitting and passes its sessionId to the SDK. Reuse the correlation id only when you intentionally want the same attempt history; use the server retake endpoint for another sitting.
Published content and locales
The Vue runtime always requests the latest compatible published copy from the configured apiBaseUrl before starting the candidate flow. Standalone ProctoringSystemCheck and ProctoringChecklist instances derive the same origin from ingestUrl. There is no content-source prop or per-host opt-in.
<ProctoredAssessment
app-id="pk_live_xxx"
correlation-id="attempt-8042"
api-base-url="https://proctor.example.com"
/>Published manifests contain platform-owned candidate copy only. They are public, cacheable data and contain no candidate, organisation, credential, or draft information. A running assessment pins the first release it receives; switching locale loads that locale from the same immutable release. A new page load revalidates the production pointer and receives newly published content without another Vue package upgrade.
Resolution order is bundled English fallback → published platform locale → explicit host messages override. A bounded timeout, network error, incompatible manifest, or invalid payload uses the bundled snapshot and does not prevent the assessment from starting. The current schema-v4 catalog centralises all platform-owned candidate copy for preflight, checklist, resume recovery, runtime startup, permission prompts and browser-specific recovery guides, candidate-intake defaults and validation, headshot and camera failures, media help, accessibility status labels, and in-assessment device settings. The bundled fallback is generated from that same framework-neutral catalog rather than authored independently in Vue.
The content schema is selected by the installed package. Older packages continue requesting their compatible schema line, while the current package requests schema v4. A new schema key or rendering contract requires a package update; editing or translating an existing schema-v4 value requires only publication and a page refresh.
Runtime values are not authored copy: candidate names, detected device names, filenames, browser and operating-system values, dimensions, speeds, timestamps, and customer-defined candidate-intake titles, sections, field labels, options, help text, and guidelines are interpolated into or displayed alongside Studio-managed templates. Raw browser, media-adapter, upload, and host callback error messages are never shown to candidates; the UI uses the published Studio recovery message while preserving typed failures and technical errors for application event handling.
Lifecycle events
| Event | When it fires | Required host action |
|---|---|---|
attempt-resolved | The server returns the current internal sitting. | Branch on canStart; an already-completed load does not emit session-ended. |
preflight-passed | The current wizard attempt passes. | Usually none; auto-start continues by default. |
preflight-failed | A candidate check fails. | Record/support the typed failure; do not parse display copy. |
session-started | Runtime evidence capture is ready. | Start or unlock your assessment timer. |
session-error | Attempt resolution, delivery readiness, or runtime startup fails. | Keep the assessment blocked and offer support/retry based on the payload. |
Use #ended for the completion UI. It renders both after a live end and when an already-completed attempt is loaded; its live boolean distinguishes those paths.
Important props
| Prop | Default | Purpose |
|---|---|---|
appId | required | Public pk_ application key sent from the browser. |
correlationId | required | Your opaque exam-attempt identity. |
apiBaseUrl | http://localhost:3001 | Proctor API origin. Set explicitly outside local development. |
ingestUrl | derived | Override only for a deliberately separate ingest route. |
preset | standard | basic, standard, or . |
The component also supports candidateIntake, submitCandidateIntake, assessmentSlug, fullscreenExitModal, contentClass, dark, and an advanced workerUrl override. Use the exported policy, event, and slot types in typed host adapters rather than recreating those contracts.
preflightUi is deliberately outside ProctoringPolicy: it changes presentation only. During controlled rollout, omit it to keep the established wizard or set preflight-ui="checklist" to show the resume-style persistent card. Every checklist step stays in that card: system and connection is first, required media checks follow, optional candidate intake appears after Camera and identity, and the final start action appears in the card footer. A required candidate-intake headshot derives a camera preflight requirement even when runtime webcam evidence is disabled; it does not enable snapshots or recording. When candidate.name is present, a user icon and localized “Welcome, FirstName” greeting appear at the left of the checklist toolbar, opposite the global Help and locale controls; no placeholder identity is inferred from email or ID. System and connection instead remains collapsed with a trailing spinner while it runs in the background and auto-advances without a Continue click on success. Only a failure expands it, and that expansion contains the failed checks' guidance rather than every successful sub-check. Every expanded system failure includes Need help?, which opens its relevant troubleshooting article; when Retry is available, both actions share the same action row. Candidate details uses the same flat expanded-card layout as the media checks: its description, configured fields, inline validation, and right-aligned Continue action render without a second nested panel, while submission failures use the shared error alert. Microphone, speaker, camera, and screen sharing use the same flat card layout and shared alerts: permission and recoverable error states keep Need help? beside the relevant action, while verified states remove Help and show only Continue. A screen-sharing failure presents the error through the shared alert and pairs Need help? with Try again; after sharing succeeds, the row keeps the browser sharing-bar guidance and presents only Continue. A hard-denied microphone or camera shows detected-browser Block → Allow instructions below the shared alert; the corresponding Need help? action opens permission recovery rather than device-quality troubleshooting. Speaker-only flows depend on microphone permission for output enumeration, so speaker denial deliberately shows the Microphone guide. On the unverified speaker screen, sits beside and opens the slideover directly at speaker troubleshooting. The confirmation checkbox remains visible but disabled before and during playback; only a successfully completed tone enables it. The speaker instruction remains unchanged before, during, and after playback. Help remains available throughout, then is removed after verification. Retry reruns only system-class checks and cannot prompt for microphone or camera; deterministic incompatibilities retain contextual help without a non-functional retry. The renderer choice never disables a required check or changes microphone VAD, speaker confirmation, camera verification, screen-share enforcement, telemetry, or runtime startup. Keep the choice fixed for the lifetime of a mounted assessment; changing it mid-preflight restarts the presentation.
The mid-assessment refresh gate uses the same checklist shell and the same system, microphone, speaker, camera, screen-sharing, and final-step components instead of a separate recovery-card implementation. Candidate identity, global Help, locale selection, and dark mode are owned by <ProctoredAssessment> and therefore remain consistent before preflight, during refresh recovery, and at the runtime handoff. The refresh probe decides which steps require attention; the shared step components own the candidate-facing permission, device-selection, verification, and recovery interactions. A lost microphone, speaker-enumeration, or camera permission clears only the affected saved device selection, so restoring access leads to a fresh selection and verification rather than silently reusing the old ID. Resume dropdown choices—including automatic defaults—remain pending until the relevant test passes and the candidate activates Continue; only then does the wrapper persist that device ID for runtime use.
| Additional prop | Default | Purpose |
|---|---|---|
candidateIntake / submitCandidateIntake | — | Host-owned candidate intake schema and awaited storage callback. |
assessmentSlug | — | Demo-assessment slug forwarded to the bundled demo resolver. Customer assessment runners should normally omit it. |
fullscreenExitModal | true | Show the wrapper's fullscreen recovery dialog. |
workerUrl | package worker factory | Advanced Worker asset override. |
contentClass | — | Class applied to the assessment content area. |
dark |
Long candidate-intake forms can be split into internal pages with candidateIntake.sections. Keep field definitions in candidateIntake.fields, then assign every field key exactly once across sections. Next validates only the visible section, Back retains entered values and files, and submitCandidateIntake still runs once after the final section with the unchanged submission payload. See Grouping long forms into sections.
Slots
| Slot | Scope | When to use it |
|---|---|---|
loading | phase | Replace the attempt-resolution loading state. The current phase is resolving-attempt. |
blocked | attempt, reason, message, retryable, activeSession, retry | Render a branded unavailable or single-active-session screen without parsing display copy. Show the retry action only when retryable is true. |
ready | attempt, sessionId, attemptNumber, |
The package exports the corresponding slot interfaces: ProctoredAssessmentLoadingSlotProps, ProctoredAssessmentBlockedSlotProps, ProctoredAssessmentReadySlotProps, ProctoredAssessmentDefaultSlotProps, and ProctoredAssessmentEndedSlotProps. It also exports event payload types, blocked reason codes, and ActiveSessionInfo so a host adapter does not need to recreate the public contract.
Building a reusable host adapter
For a client application with its own test engine, create one thin adapter component around <ProctoredAssessment>. The adapter should:
- map the host's stable attempt id to
correlationId; - supply the public app key and Proctor API origin explicitly from the host's environment;
- map the authenticated candidate to the
candidateobject; - pause and resume the host timer through the awaited integrity callbacks;
- render the host's runner in
#defaultand its completion page in#ended; - render branded
#loadingand#blockedstates when required; and - save the host's answers before awaiting
endSession().
Keep host-specific stores, routes, answer formats, and question components inside that adapter or runner. Do not put them into the ProctorKit package. Avoid a process-wide mutable configuration singleton when the application can render more than one tenant, uses server-side rendering, or runs integration tests in the same process; explicit props or an app-scoped Vue provider are safer.
The Proctor API transport, evidence delivery checks, lock heartbeat, and teardown ordering intentionally remain component-owned. They are part of the proctoring integrity contract rather than client extension points.
Screen sharing and user activation
The wrapper avoids the raw SDK activation trap. Its final preflight action remains a direct user gesture, the nested wizard uses flushBeforePass: false, and the wrapper requests/attaches the runtime screen stream before asynchronous session work consumes activation. If sharing stops mid-test, the wrapper locks the content and presents a fresh action to share again.
Keep the wrapper's start control in the live document. Do not trigger the strict-policy transition from a timer, route watcher, or resolved promise.
Policy ownership
Provide preset plus a minimal policyOverrides. Do not also hand-author raw SDK observers for the same component. The wrapper enforces these invariants:
preflight.enableddetermines whether the wizard runs.webcam.modeis exactly one ofnone,snapshots, orrecording.- camera preflight and the face reference are derived from an active webcam mode, or from a required candidate-intake headshot without enabling runtime webcam evidence.
webcam.faceAnalysis.gazeandidentityMismatchdefault totruefor active webcam modes.- evidence-delivery verification and the VAD-to-RMS fallback are internal and cannot be disabled by client policy.
See the complete policy reference and preflight wizard.
Host responsibilities
The wrapper does not own assessment answers, your timer, eligibility, accommodations, candidate support, legal notice/consent, or the final business decision. Save answers to your backend, await endSession, and reconcile the server outcome. For operational rollout, follow the controlled-trial checklist.