Skip to main content

Panes Overview

Panes are the heart of SolidOS — modular UI components that render Solid data.

What is a Pane?

A pane is a self-contained module that:

  • Declares what data types it can render
  • Provides a UI for viewing/editing that data
  • Integrates with the SolidOS ecosystem

Think of panes like "apps" in an operating system, but for data types.

Built-in Panes

SolidOS includes many panes out of the box:

PaneRendersDescription
folderldp:ContainerFile browser for pods
contactsvcard:IndividualContact cards, address books
chatmeeting:LongChatReal-time messaging
meetingmeeting:MeetingMeetings with agendas
profileWebID profilesUser profile pages
sourceAny textRaw source code/data
imageImagesPhoto viewer/slideshow
videoVideosVideo player
issuewf:IssueIssue tracking

How Panes Are Selected

When you navigate to a resource:

1. SolidOS fetches the resource
2. Determines its RDF types
3. Asks each pane: "Can you render this?"
4. Panes respond with a label or null
5. Most specific pane wins
6. That pane renders the UI

Selection Priority

// More specific = higher priority
contactPane.label(aliceContact) // Returns "Contact" (specific)
tablePane.label(aliceContact) // Returns "Data" (generic)
// contactPane wins!

The Pane Interface

Every pane implements this interface:

interface PaneDefinition {
// Unique identifier
name: string

// Icon (emoji or URI)
icon?: string

// Developer info
dev?: {
name: string
repo?: string
}

// Can this pane render the subject?
label: (
subject: NamedNode,
context: any
) => string | null

// Render the pane
render: (
subject: NamedNode,
dom: Document,
context: any
) => HTMLElement
}

Pane Categories

Data Type Panes

Render specific RDF types:

  • Contact pane → vcard:Individual
  • Meeting pane → meeting:Meeting
  • Issue pane → wf:Issue

Container Panes

Render collections:

  • Folder pane → ldp:Container
  • Address book → vcard:AddressBook
  • Chat → meeting:LongChat

Utility Panes

Always available:

  • Source pane — view raw data
  • Internals pane — debug information
  • Table pane — generic RDF viewer

Nesting Panes

Panes can embed other panes:

render: (subject, dom, context) => {
const container = dom.createElement('div')

// Get the appropriate pane for a related resource
const authorPane = paneRegistry.bySubject(author)

// Embed it
const authorElement = authorPane.render(author, dom, context)
container.appendChild(authorElement)

return container
}

Pane Context

The context object provides:

interface PaneContext {
dom: Document // The DOM document
div: HTMLElement // Container element
store: IndexedFormula // The RDF store
session: any // Authentication session
noun: string // Readable name for the subject
solo: boolean // Is this the only pane?
}

Registering Panes

Panes must be registered with the pane registry:

import { paneRegistry } from 'pane-registry'
import myPane from './myPane'

paneRegistry.register(myPane)

In solid-panes, this happens in registerPanes.ts.

Creating Custom Panes

See Creating Panes for a step-by-step guide.

Pane Lifecycle

1. Registration
↓ paneRegistry.register(pane)
2. Selection
↓ pane.label(subject) → "My Label"
3. Rendering
↓ pane.render(subject, dom, context) → HTMLElement
4. Updates
↓ Store changes trigger re-renders (if subscribed)
5. Cleanup
↓ Element removed from DOM

See Also