SSR Rendering Test — Complete Element Coverage

This document exercises every block and inline element to compare SSR (subdomain) vs CSR (editor) rendering.


Typography Scale

Heading 1 — The Biggest Title

Heading 2 — Section Header

Heading 3 — Subsection

Heading 4 — Minor Section

Heading 5 — Small Label
Heading 6 — Smallest

Regular paragraph text at 16px base. This is the default prose body with proper line-height (1.7) and letter-spacing (-0.003em). The system font stack should render crisply across all platforms.


Inline Formatting

This paragraph has bold text, italic text, bold italic, strikethrough, inline code, and a hyperlink. Here is highlighted text and green highlight and blue highlight and red highlight.

Mixing inline styles: bold with inline code inside and italic with a link inside.


Block Quotes

Simple blockquote — a single line of quoted text with left border accent.

Multi-line blockquote that spans several sentences to test wrapping behavior. The left border should extend the full height. Text color should be muted compared to body text.

Second paragraph inside the same blockquote to verify paragraph spacing within quotes.


Callout Boxes

This is a note callout. Used for supplementary information that adds context without being critical.

This is a tip callout. Suggests best practices or shortcuts the reader might find useful.

This is a warning callout. Alerts the reader to potential pitfalls or important caveats.

This is a caution callout. Indicates danger or a high-risk action that could cause problems.

This is an important callout. Highlights crucial information the reader should not skip.


Lists

Unordered List

Ordered List

  1. First numbered item

  2. Second numbered item

    1. Nested numbered 2.1

    2. Nested numbered 2.2

  3. Third item with a longer description that wraps to multiple lines to test alignment of subsequent lines with the number indent

Task List


Tables

Simple Table

Feature

Status

Notes

Syntax Highlighting

Active

Shiki via CDN

Mermaid Diagrams

Active

Full zoom/pan/fullscreen

Math Rendering

Active

KaTeX via CDN

Dark Mode

Active

MutationObserver on .dark

Copy Button

Active

Clipboard API

Wide Table (Overflow Test)

Component

File Path

Size

Dependencies

Build Time

CDN Loaded

SSR Compatible

Dark Mode

CodeBlockView

packages/block-editor/src/ui/CodeBlock/CodeBlockView.component.tsx

200 lines

lucide-react, LanguagePicker

0.5s

No

Yes

Yes

CodeBlockIsland

packages/block-editor/src/ui/CodeBlock/CodeBlockIsland.component.tsx

280 lines

dynamicImport, MermaidPreview, MathPreview

0.3s

shiki, mermaid, katex

Yes

Yes

MermaidRenderer

packages/block-editor/src/ui/CodeBlock/renderers/MermaidRenderer.component.tsx

355 lines

mermaid, lucide-react

0.8s

No

No

Yes


Code Blocks

JavaScript

async function mountCodeBlockIslands() {
  const blocks = document.querySelectorAll('pre.block-code-block');
  if (blocks.length === 0) return;

  const theme = detectTheme();

  blocks.forEach((pre) => {
    const codeEl = pre.querySelector('code');
    if (!codeEl) return;

    const code = codeEl.textContent || '';
    const language = codeEl.getAttribute('data-language') || 'plaintext';

    const wrapper = document.createElement('div');
    wrapper.className = 'code-block-nodeview';
    pre.replaceWith(wrapper);

    createRoot(wrapper).render(
      createElement(CodeBlockIsland, { code, language, theme })
    );
  });
}

TypeScript

interface CodeBlockViewProps {
  language: string;
  theme: 'light' | 'dark';
  readOnly: boolean;
  viewMode: ViewMode;
  showLineNumbers: boolean;
  wordWrap: boolean;
  copied: boolean;
  highlightHtml: string;
  diffHtml: string;
  onViewModeChange?: (mode: ViewMode) => void;
  onLanguageChange?: (lang: string) => void;
  onCopy?: () => void;
  contentSlot: ReactNode;
  previewSlot?: ReactNode;
  lineCount: number;
}

type ViewMode = 'code' | 'preview' | 'split';

Python

class MermaidRenderer:
    """Renders mermaid diagrams with dark mode support."""

    ZOOM_STEP = 0.25
    MIN_ZOOM = 0.25
    MAX_ZOOM = 5.0

    def __init__(self, theme: str = "light"):
        self.theme = theme
        self.config = self._get_config()

    def _get_config(self) -> dict:
        return {
            "startOnLoad": False,
            "securityLevel": "strict",
            "theme": "dark" if self.theme == "dark" else "base",
            "fontFamily": "-apple-system, BlinkMacSystemFont, sans-serif",
        }

    async def render(self, code: str) -> str:
        svg = await self._mermaid_render(code)
        if self.theme == "dark":
            svg = self._adapt_colors_for_dark(svg)
        return svg

CSS

.code-block-wrapper {
  position: relative;
  border: 1px solid var(--be-border, #e5e7eb);
  border-radius: 0.5rem;
  overflow: hidden;
  background: var(--be-code-bg, #f8f9fa);
  font-family: "JetBrains Mono", "Fira Code", "Cascadia Code",
    "Menlo", "Monaco", "Consolas", monospace;
  font-size: 0.875rem;
  line-height: 1.5;
  transition: border-color 0.15s ease;
}

.code-block-wrapper--dark {
  background: var(--be-code-bg-dark, #1e1e2e);
  border-color: var(--be-border-dark, #313244);
}

.dark .block-table th {
  background: var(--table-header-bg, #2d3748);
  color: var(--table-header-text, #e2e8f0);
}

Bash

#!/bin/bash
# Deploy subdomain worker to Cloudflare
cd apps/subdomain
yarn build

echo "Bundle size: $(du -sh dist/server/ | cut -f1)"
echo "Chunk count: $(ls dist/server/chunks/ | wc -l)"

CLOUDFLARE_API_TOKEN="$CLB_CLOUDFLARE_API_TOKEN" yarn deploy

echo "Deployed successfully!"

JSON

{
  "name": "@colbin/block-editor",
  "version": "0.1.0",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.js",
      "require": "./dist/index.cjs"
    },
    "./islands/codeblock": "./src/ui/CodeBlock/mountCodeBlockIslands.ts",
    "./styles.css": "./dist/block-editor.css"
  },
  "peerDependencies": {
    "shiki": "^3.0.0",
    "mermaid": "^11.0.0",
    "katex": "^0.16.0",
    "react": "^19.0.0"
  }
}

Diff

- import { MermaidRenderer } from './renderers/MermaidRenderer.component';
- import { MathRenderer } from './renderers/MathRenderer.component';
+ // Renderers moved to previewSlot — injected by consumers
+ // Editor passes bundled renderers, SSR island passes CDN-loaded ones

  export const CodeBlockView = React.memo(({
-   code,
    language,
    theme,
    readOnly,
+   previewSlot,
    contentSlot,
  }) => {

Mermaid Diagrams

Flowchart

flowchart TD
    SSR[SSR HTML Response] --> Hydrate[React Island Hydration]
    Hydrate --> Detect{Detect Theme}
    Detect -->|Light| Light[Light Config]
    Detect -->|Dark| Dark[Dark Config]
    Light --> Mount[Mount CodeBlockIslands]
    Dark --> Mount
    Mount --> Shiki[Shiki CDN Highlight]
    Mount --> Mermaid[Mermaid CDN Render]
    Mount --> KaTeX[KaTeX CDN Render]
    Shiki --> Display[Display Enhanced Blocks]
    Mermaid --> Display
    KaTeX --> Display

    style SSR fill:#4a9eff,color:#fff
    style Display fill:#10b981,color:#fff
    style Detect fill:#f59e0b,color:#fff

Sequence Diagram

sequenceDiagram
    participant B as Browser
    participant W as CF Worker
    participant A as API Server
    participant C as CDN (esm.sh)

    B->>W: GET org.colbin.com/bin/slug
    W->>A: Fetch pre-rendered HTML
    A-->>W: HTML + metadata
    W-->>B: Full SSR page

    Note over B: React island hydrates (client:idle)

    B->>C: import('shiki')
    C-->>B: Shiki bundle
    B->>C: import('mermaid')
    C-->>B: Mermaid bundle

    Note over B: Code blocks enhanced with<br/>syntax highlighting + diagrams

    B->>B: User toggles dark mode
    Note over B: MutationObserver fires<br/>Re-render all islands

Math / LaTeX

E = mc^2
\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
\frac{\partial f}{\partial x} = \lim_{h \to 0} \frac{f(x+h) - f(x)}{h}

Horizontal Rules

Content above the rule.


Content below the rule. Rules should have consistent vertical spacing.


Mixed Content Stress Test

Here is a paragraph with bold, italic, inline code, and a link. It references the CodeBlockView component which accepts a previewSlot?: ReactNode prop.

The dynamicImport() function uses new Function() to bypass Vite's static analysis. This is guarded with typeof window === 'undefined' for Cloudflare Workers compatibility.

Below is a table followed immediately by a code block:

Approach

Bundle Size

CDN Load

Bundled

19 MiB

None

CDN

1.7 MiB

~2 MiB async

// The dynamicImport trick that saved 17MB
function dynamicImport(specifier: string): Promise<any> {
  if (typeof window === 'undefined') {
    return Promise.reject(new Error('client-only'));
  }
  return new Function('s', 'return import(s)')(specifier);
}

And a mermaid diagram right after:

graph LR
    A[19 MiB Bundle] -->|CDN externalize| B[1.7 MiB Bundle]
    B -->|+ esm.sh| C[Full Features]
    style A fill:#ef4444,color:#fff
    style B fill:#10b981,color:#fff
    style C fill:#3b82f6,color:#fff

End of rendering test document. Compare this page between SSR (subdomain) and CSR (editor) for visual parity.