This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/docs/TUTORIAL-FIRST-EXTENSION.md
Jeffrey Smith 2adaabe5fa
All checks were successful
CI/CD / detect-changes (pull_request) Successful in 4s
CI/CD / test-frontend (pull_request) Successful in 6s
CI/CD / test-go-pg (pull_request) Successful in 2m43s
CI/CD / test-sqlite (pull_request) Successful in 2m51s
CI/CD / build-and-deploy (pull_request) Successful in 1m13s
v0.6.5: Renderer pipeline, docs rewrite, architecture diagrams
Lift block rendering to kernel SDK primitives (sw.renderers + sw.markdown)
so all surfaces share one markdown pipeline. Rewrite docs for external
audience — remove all fork history references. Add Mermaid architecture
diagrams, CONTRIBUTING guide, and extension tutorial.

- sw.renderers SDK module: kernel-level renderer registry
- sw.markdown SDK module: unified marked v16 + DOMPurify pipeline
- Browser extension script loader for renderer injection
- Notes + Docs surfaces migrated to sw.markdown.renderSync()
- 4 renderer extensions rewritten to IIFE + sw.renderers.register()
- 6 Mermaid diagrams in ARCHITECTURE.md
- CONTRIBUTING.md + TUTORIAL-FIRST-EXTENSION.md
- DESIGN-WORKFLOWS.md replaces fork-era design doc
- Surface alias routes removed from main.go
- ICD/SDK runners migrated to /admin/packages/ endpoints
- 13 new renderer tests
- Docs, CHANGELOG, ROADMAP cleaned of fork references

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 15:26:44 +00:00

3.6 KiB

Build Your First Browser Extension

This tutorial walks through building a browser extension that renders custom code blocks, modeled on the CSV Table Viewer that ships with Switchboard.

Prerequisites: A running Switchboard instance, a text editor, and zip.

Step 1: Create the Directory

mkdir -p my-extension/js

Step 2: Write the Manifest

Create my-extension/manifest.json:

{
    "id": "my-extension",
    "title": "My Extension",
    "version": "0.1.0",
    "type": "extension",
    "tier": "browser",
    "author": "you",
    "description": "Renders demo code blocks as styled HTML",
    "permissions": [],
    "settings": {}
}
  • id -- unique identifier, used as the install key
  • type -- extension for browser-only packages; full or surface for packages with backend routes
  • tier -- browser for client-side JS; starlark for server-side scripting

Step 3: Write the Browser Script

Create my-extension/js/script.js. Browser extensions use the IIFE pattern and register with the SDK through sw.renderers:

(function () {
    'use strict';

    function register() {
        if (!window.sw?.renderers) return;

        sw.renderers.register('demo-block', {
            type: 'block',
            priority: 10,
            match(lang) {
                return (lang || '').toLowerCase() === 'demo';
            },
            render(lang, code, container) {
                container.innerHTML =
                    '<div style="padding:12px;background:var(--bg-2);' +
                    'border:1px solid var(--border);border-radius:8px">' +
                    '<strong>Demo:</strong> ' + code +
                    '</div>';
            }
        });
    }

    if (window.sw?._sdk) {
        register();
    } else {
        document.addEventListener('sw:ready', register, { once: true });
    }
})();

The IIFE wrapper keeps variables out of global scope. sw.renderers.register takes a name and an options object: type: 'block' targets fenced code blocks, match checks the language tag, and render receives the language, raw code, and a container element. The sw:ready event fires once the SDK initializes; if already loaded, register immediately. Use CSS variables like var(--bg-2) and var(--border) to follow the active theme.

Step 4: Package It

cd my-extension
zip -r ../my-extension.pkg manifest.json js/

The .pkg format is a ZIP with manifest.json at the root. Optional directories: js/, css/, assets/. If working inside packages/, use the build script instead: bash build.sh my-extension.

Step 5: Install It

curl -X POST http://localhost:3000/api/v1/admin/packages/install \
  -H "Authorization: Bearer <token>" \
  -F "file=@my-extension.pkg"

You can also install through the Admin UI under the Packages section.

Step 6: Enable and Test

  1. Open the admin panel, navigate to Packages, confirm "My Extension" is enabled.
  2. Go to any markdown surface (Chat, Notes, etc.).
  3. Enter a fenced code block with the demo language tag.

You should see styled output instead of a plain code block.

Going Further

  • Add CSS -- create a css/ directory; stylesheets are injected automatically.
  • Post-renderers -- register with type: 'post' to run after block renderers finish (the Mermaid extension uses this for async SVG rendering).
  • Settings -- declare a settings object in the manifest for admin-configurable values.
  • Server-side logic -- set tier: "starlark" and add script.star for backend API routes and database tables.

See PACKAGE-FORMAT.md for the full manifest spec and EXTENSION-GUIDE.md for advanced patterns.