Skip to content

Integration Guide (React Next.js Vite)

Ved Gupta edited this page Oct 15, 2026 · 2 revisions

Integration Guide

How to integrate @innovatorved/code-lab (v2.0.0) into React, Next.js, Vite, and static HTML / CDN environments.


Package & CDN Installation (v2.0.0)

NPM / Bun

bun add @innovatorved/code-lab
# or
bun add @innovatorved/code-lab

Static HTML / CDN — jsDelivr (v2.0.0)

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@innovatorved/code-lab@2.0.0/dist/code-lab.css">
<script src="https://cdn.jsdelivr.net/npm/@innovatorved/code-lab@2.0.0/dist/code-lab.js"></script>

Static HTML / CDN — unpkg (v2.0.0)

<link rel="stylesheet" href="https://unpkg.com/@innovatorved/code-lab@2.0.0/dist/code-lab.css">
<script src="https://unpkg.com/@innovatorved/code-lab@2.0.0/dist/code-lab.js"></script>

1. React Integration

Create a reusable CodeLabEditor component:

// CodeLabEditor.tsx
import React, { useEffect, useRef } from 'react';
import CodeLab, { CodeLabWorkbench, CodeLabOptions } from '@innovatorved/code-lab';
import '@innovatorved/code-lab/dist/code-lab.css';

interface CodeLabProps extends CodeLabOptions {
  className?: string;
  style?: React.CSSProperties;
}

export const CodeLabEditor: React.FC<CodeLabProps> = ({ className, style, ...options }) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const workbenchRef = useRef<CodeLabWorkbench | null>(null);

  useEffect(() => {
    if (!containerRef.current) return;

    // Mount workbench
    workbenchRef.current = CodeLab.mount(containerRef.current, {
      ...options,
      persistState: options.persistState ?? true
    });

    // Cleanup on unmount
    return () => {
      if (workbenchRef.current) {
        workbenchRef.current.destroy();
        workbenchRef.current = null;
      }
    };
  }, [options.id]);

  return (
    <div
      ref={containerRef}
      className={className}
      style={{ width: '100%', height: '100%', minHeight: '600px', ...style }}
    />
  );
};

Usage in React

import { CodeLabEditor } from './CodeLabEditor';

export function App() {
  return (
    <div style={{ height: '100vh', width: '100vw' }}>
      <CodeLabEditor
        id="react-demo-lab"
        title="Distributed KV Store"
        mode="sandbox"
        language="ts"
        entry="index.ts"
        files={{
          'index.ts': 'console.log("KV Store initialized");',
          'store.ts': 'export class Store { private m = new Map(); }'
        }}
        onRun={(res) => console.log('Run finished:', res)}
      />
    </div>
  );
}

2. Next.js (App Router / SSR)

Because Monaco Editor and Web Workers require browser APIs (window, Worker, Blob), use dynamic client loading:

// app/labs/[slug]/page.tsx
'use client';

import dynamic from 'next/dynamic';

const CodeLabEditor = dynamic(
  () => import('./CodeLabEditor').then((mod) => mod.CodeLabEditor),
  { ssr: false, loading: () => <div style={{ background: '#0a0a0a', height: '100vh', color: '#888', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>Loading CodeLab IDE...</div> }
);

export default function LabPage({ params }: { params: { slug: string } }) {
  return (
    <main style={{ height: '100vh' }}>
      <CodeLabEditor
        id={`lab-${params.slug}`}
        title={`Lab: ${params.slug}`}
        mode="guided"
        language="js"
        files={{
          'demo.js': 'console.log("Demo running");',
          'test.js': 'const { test } = require("node:test"); test("ok", () => {});'
        }}
      />
    </main>
  );
}

3. Vite / Vanilla ESM

// main.ts
import CodeLab from '@innovatorved/code-lab';
import '@innovatorved/code-lab/dist/code-lab.css';

const container = document.getElementById('app')!;

const lab = CodeLab.mount(container, {
  id: 'vite-sandbox',
  title: 'Vite Embedded CodeLab',
  mode: 'sandbox',
  language: 'ts',
  files: {
    'index.ts': 'console.log("Vite + CodeLab");'
  }
});

// Imperative API access
lab.on('change', () => {
  console.log('Files changed:', lab.getFiles());
});

4. Theming (Dark / Light / Auto)

CodeLab uses the Geist Monochrome design system with semantic CSS tokens.

To enforce theme programmatically:

CodeLab.mount('#editor', {
  theme: 'dark', // 'dark' | 'light' | 'auto'
  // ...
});

To sync with your website's data-theme attribute, CodeLab automatically inspects:

  1. document.documentElement.getAttribute('data-theme')
  2. options.theme
  3. prefers-color-scheme media query

You can override variables in your stylesheet:

/* Custom theme overrides */
.codelab-workbench {
  --cl-bg: #0d1117;
  --cl-bg-panel: #161b22;
  --cl-border: #30363d;
  --cl-fg: #f0f6fc;
}

Clone this wiki locally