# Embedding Apps

## Basic Iframe Embed

Every SGApps web application is available at:

```
https://sgapps.io/online/webapp/{app-name}
```

Embed with a standard `<iframe>`:

```html
<iframe
    id="sgapps-editor"
    src="https://sgapps.io/online/webapp/photo-editor"
    width="100%"
    height="600"
    frameborder="0"
    allow="camera; microphone; clipboard-write"
></iframe>
```

### Recommended `allow` Attributes

| Permission | Needed By |
|-----------|-----------|
| `camera` | Recorder |
| `microphone` | Recorder, ChatBox |
| `clipboard-write` | Code Editor, File Manager |
| `fullscreen` | All apps (fullscreen button) |

## URL Patterns

### Default (Demo Mode)

```
/online/webapp/{app-name}
```

Opens the app with its default demo arguments (if configured). For Photo Editor this loads a sample image.

### Open a Remote URL

```
/online/webapp/{app-name}/url/{base64-encoded-url}
```

The third segment is the URL base64-encoded with `btoa()`:

```js
var url = "https://example.com/image.jpg";
var src = "https://sgapps.io/online/webapp/photo-editor/url/" + btoa(url);
```

### Open a File by Path

```
/online/webapp/{app-name}/file/{base64-encoded-path}
```

For authenticated users, opens a file from their GridFS storage.

## Embed Mode

By default, the app renders with window chrome (title bar, controls). For a cleaner embed, enable **embed mode** via the WindowSocket API:

```js
socket.fire("webapp::instance::embed-mode", true, function (err, isEmbedded) {
    // App is now maximized with no title bar
});
```

This:
- Hides the window header (title bar, close/minimize/maximize buttons)
- Maximizes the app to fill the entire iframe
- Adds `webapp-instance--embed-mode` class to the body

Disable embed mode:

```js
socket.fire("webapp::instance::embed-mode", false, function (err, isEmbedded) {
    // Window chrome is restored
});
```

## Responsive Sizing

The webapp container auto-resizes to fill the iframe viewport. A polling loop (500ms) adjusts the container height to account for the top bar and footer. For best results, set the iframe to fill its parent:

```css
iframe {
    width: 100%;
    height: 100vh;
    border: none;
}
```

## Cross-Origin Considerations

The apps are hosted on `sgapps.io`. When embedding from a different domain, the WindowSocket API uses `postMessage` which works cross-origin. No special CORS headers are needed for the iframe itself, but if you need to load files from your domain into the app, they must be accessible via a public URL.

## App Name Reference

| App Name | URL Slug |
|----------|----------|
| Photo Editor | `photo-editor` |
| SVG Editor | `svg-editor` |
| Code Editor | `code-editor` |
| Archive Viewer | `archive-viewer` |
| Media Player | `media-player` |
| Recorder | `recorder` |
| File Manager | `file-manager` |
| Presentation | `presentation` |
| GCode Editor | `gcode-editor` |
| CNC GCode Simulator | `cnc-gcode-simulator` |
| ChatBox | `chatbox` |
| SVFS Manager | `svfs-manager` |
| SSH Web Client | `ssh-web-client` |
