Skip to main content
This is a Frontend SDK method. It runs in the browser — import it in your React/Next.js component, not on the server.

Install

npm install @recordorg/smartai-assessment-frontend

How it works

Two steps only:
  1. Call your backend to get a token
  2. Call AssessmentPortal.open({ token, apiKey }) — the iframe opens and the candidate takes the test
Recruiter clicks "SmartAI Assessment"

    ├─ Step 1: Call YOUR backend endpoint
    │   POST /assessment/session
    │   { users: [...] }
    │   ◀── { success: true, data: { token } }

    └─ Step 2: Open the portal
        AssessmentPortal.open({ token, apiKey })

        ┌──────────────────────────────────────────┐
        │          IFRAME (full screen)             │
        │                                           │
        │   SmartAI Assessment UI loads here        │
        │   Candidate takes the test                │
        │   Results go to your backend via polling  │
        │                                           │
        └──────────────────────────────────────────┘
Results are collected on your server by polling — not via the onDone callback. The onDone / onClose callbacks are only for updating your UI (e.g. showing a toast message).

Signature

AssessmentPortal.open(options: AssessmentPortalOptions): void

Parameters

token
string
required
The session token from your backend. This is response?.data?.token from your assessmentApi.createSession() call.Never hardcode this — always fetch it fresh from your backend first.
apiKey
string
Your SmartAI public API key. This tells the portal which environment to load (live or test).Where to get it: Same key you use on the backend as ASSESSMENT_API_KEY. The difference is how you expose it:
VariableUsed inSafe to expose?
ASSESSMENT_API_KEYBackend .envServer only — never sent to browser
NEXT_PUBLIC_ASSESSMENT_API_KEYFrontend .env.local✅ Safe — same key, public prefix
Setup — add this to your frontend .env.local:
# .env.local  (your Next.js frontend)
NEXT_PUBLIC_ASSESSMENT_API_KEY=wc_test_your_key_here
Use it in code:
const apiKey = process.env.NEXT_PUBLIC_ASSESSMENT_API_KEY;
Never add ASSESSMENT_SECRET_KEY to a NEXT_PUBLIC_ variable. The secret key signs requests and must stay on the server only. Only the API key (not the secret) goes in the frontend env.
onDone
function
(result: { assessmentId: string }) => voidCalled when the candidate successfully submits the assessment. This is your signal to show a success message to the recruiter.
onDone: () => toast.success('Assessment sent successfully!')
onClose
function
() => voidCalled when the candidate closes the portal without submitting. The assessment is not complete — no result will appear in the webhook queue.
onClose: () => {}  // or show a warning toast
onError
function
(error: Error) => voidCalled when something goes wrong — invalid token, network failure, etc.
onError: (err: Error) => toast.error(err.message || 'Assessment failed')
zIndex
number
default:"9999"
CSS z-index of the overlay. Increase if your app has elements that appear on top of the iframe (sidebars, modals with very high z-index).

const handleOpenAssessment = async () => {
  setAssessmentLoading(true);

  try {
    // Step 1: Build the users list from your shortlisted candidates
    const payload = {
      users: data.map(c => ({
        name:  c.name ?? c.fullName ?? '',
        email: c.email ?? '',
      })),
    };

    // Step 2: Call your backend to get a session token
    const response = await assessmentApi.createSession(payload.users);
    const token  = response?.data?.token;
    const apiKey = process.env.NEXT_PUBLIC_ASSESSMENT_API_KEY;

    // Step 3: Guard checks
    if (!token)  throw new Error('No session token received');
    if (!apiKey) throw new Error('Assessment API key is not configured');

    // Step 4: Dynamically import (required for Next.js — avoids SSR error)
    const { default: AssessmentPortal } = await import(
      '@recordorg/smartai-assessment-frontend'
    );

    // Step 5: Open the portal
    AssessmentPortal.open({
      token,
      apiKey,
      onDone:  () => toast.success('Assessment sent successfully!'),
      onClose: () => {},
      onError: (err: Error) => toast.error(err.message || 'Assessment failed'),
    });

  } catch (error: any) {
    toast.error(error?.message || 'Failed to open assessment');
  } finally {
    setAssessmentLoading(false);
  }
};

Why await import(...) instead of a regular import?

// ❌ This will crash in Next.js (server-side render error)
import AssessmentPortal from '@recordorg/smartai-assessment-frontend';

// ✅ This works — loads only in the browser, never on the server
const { default: AssessmentPortal } = await import('@recordorg/smartai-assessment-frontend');
The frontend SDK uses window and document, which don’t exist during Next.js server-side rendering. The dynamic import tells Next.js to load this package only when the code actually runs in the browser.

TypeScript type declaration

If your IDE shows “cannot find module” or type errors:
// src/types/smartai-assessment-frontend.d.ts
declare module '@recordorg/smartai-assessment-frontend' {
  interface AssessmentPortalOptions {
    token:    string;
    apiKey?:  string;
    baseUrl?: string;
    zIndex?:  number;
    onDone?:  (result: { assessmentId: string }) => void;
    onClose?: () => void;
    onError?: (error: Error) => void;
  }

  const AssessmentPortal: {
    open(opts: AssessmentPortalOptions): void;
    close(): void;
    isOpen(): boolean;
  };

  export default AssessmentPortal;
}

Common mistakes

MistakeWhat happensFix
Static import in Next.jsReferenceError: window is not definedUse await import(...) instead
Forgetting apiKeyPortal uses wrong environmentPass process.env.NEXT_PUBLIC_ASSESSMENT_API_KEY
Calling open() before getting the tokentoken is undefinedAlways await your session API call first
Not handling onErrorSilent failure, user confusedAlways show a toast or alert in onError
Calling open() twiceTwo overlapping iframesCheck AssessmentPortal.isOpen() first