Surfaces extend your extension's UI across predefined locations in the host application. This guide walks you through creating and registering a new surface.

## 1. Determine the target slot

Identify which target slot this surface should occupy. Valid targets are:

- `slot.header` — appears at the top of the extension area
- `slot.content` — main content area
- `slot.footer` — bottom of the extension area
- `slot.footer-links` — footer link row

## 2. Create the surface file

Create a new file in `packages/extension/src/surfaces/` named after the slot (for example, `Header.tsx`, `Content.tsx`, `Footer.tsx`).

Use this template:

```tsx
import { Surface, useCapabilities, useContextData } from '@stackable-labs/sdk-extension-react'
import { ui } from '@stackable-labs/sdk-extension-react'

export const [SurfaceName] = () => {
  return (
    <Surface id="[target]">
      {/* Surface content here */}
    </Surface>
  )
}
```

If the surface needs state management, import and use the existing store from `../store`.

## 3. Register the surface in index.tsx

Import the new surface component and add it to the `createExtension` factory function alongside existing surfaces.

## 4. Update manifest.json

Add the target to the `targets` array in `packages/extension/public/manifest.json`. Also add any required permissions based on the target-permission mapping:

- `slot.header` → `context:read`
- `slot.content` → `context:read`, `data:query`, `actions:toast`, `actions:invoke`, `messaging:send`
- `slot.footer` → (none)
- `slot.footer-links` → (none)

Only add permissions that are not already declared.

## 5. Verify

- Confirm the surface renders by checking the import chain: index.tsx → Surface component → Surface id matches manifest target
- Confirm manifest.json is valid JSON with no duplicate targets or permissions
