mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 01:45:10 +03:00
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Adds a new Realtime Monaco component to the UI Library, enabling collaborative code editing with Supabase Realtime synchronization using Monaco Editor and Yjs. ## Additional context This is WIP and used for discuss further changes to the y-supabase provider. ## Demo https://github.com/user-attachments/assets/84a761e5-73bb-478e-979a-682121ffee89 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Added a new Realtime Monaco collaborative code editor component with real-time synchronization support across multiple frameworks (Next.js, React, React Router, Tanstack). * **Documentation** * Added comprehensive documentation and usage guides for the Realtime Monaco component across all supported frameworks. * **Dependencies** * Added Monaco editor, Yjs, y-monaco, and Supabase collaboration packages. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
125 lines
5.7 KiB
Plaintext
125 lines
5.7 KiB
Plaintext
---
|
|
title: Realtime Monaco
|
|
description: Real-time Monaco editor for collaborative applications
|
|
---
|
|
|
|
<DualRealtimeMonaco />
|
|
|
|
## Installation
|
|
|
|
<BlockItem
|
|
name="realtime-monaco-tanstack"
|
|
description="Real-time Monaco editor for collaborative applications."
|
|
/>
|
|
|
|
## Folder structure
|
|
|
|
<RegistryBlock itemName="realtime-monaco-tanstack" />
|
|
|
|
## Introduction
|
|
|
|
The Realtime Monaco component provides a collaborative code editor powered by [Monaco](https://microsoft.github.io/monaco-editor/) and [Yjs](https://yjs.dev/). It uses [`@supabase-labs/y-supabase`](https://github.com/supabase-community/y-supabase) under the hood to sync document state across clients through Supabase Realtime.
|
|
|
|
**Features**
|
|
|
|
- Real-time document synchronization via Supabase Realtime broadcast
|
|
- Cursor and selection sharing between collaborators (awareness)
|
|
- Optional persistence to Postgres so documents survive page reloads
|
|
- Supports all Monaco languages and themes
|
|
- Room-based isolation for scoped collaboration
|
|
|
|
## How it works under the hood
|
|
|
|
The component creates a [Yjs](https://yjs.dev/) document and connects it to a Supabase Realtime channel using `SupabaseProvider` from `@supabase-labs/y-supabase`. A `MonacoBinding` from `y-monaco` bridges the Yjs document with the Monaco editor model, keeping them in sync.
|
|
|
|
When **awareness** is enabled, each user's cursor position and selection are broadcast to other clients in the same channel. Remote cursors are rendered with unique colors via dynamically injected CSS.
|
|
|
|
When **persistence** is enabled, the full Yjs document state is saved to a Postgres table so it can be restored when clients reconnect.
|
|
|
|
## Usage
|
|
|
|
### Basic usage
|
|
|
|
```tsx
|
|
import { RealtimeMonaco } from '@/components/realtime-monaco'
|
|
|
|
export default function MonacoPage() {
|
|
return <RealtimeMonaco channel="realtime-monaco-demo" language="typescript" />
|
|
}
|
|
```
|
|
|
|
### With persistence
|
|
|
|
Enable persistence to save the editor content to your Supabase database. This requires a table to store the Yjs document state.
|
|
|
|
First, create the required table in your Supabase project:
|
|
|
|
```sql
|
|
create table yjs_documents (
|
|
room text primary key,
|
|
state text not null
|
|
);
|
|
```
|
|
|
|
Then pass `persistence` to the component:
|
|
|
|
```tsx
|
|
import { RealtimeMonaco } from '@/components/realtime-monaco'
|
|
|
|
export default function MonacoPage() {
|
|
return <RealtimeMonaco channel="realtime-monaco-demo" language="typescript" persistence />
|
|
}
|
|
```
|
|
|
|
You can also pass a `SupabasePersistenceOptions` object:
|
|
|
|
```tsx
|
|
<RealtimeMonaco
|
|
channel="realtime-monaco-demo"
|
|
language="typescript"
|
|
persistence={{
|
|
table: 'yjs_documents',
|
|
roomColumn: 'room',
|
|
stateColumn: 'state',
|
|
storeTimeout: 2000,
|
|
}}
|
|
/>
|
|
```
|
|
|
|
### Without awareness
|
|
|
|
By default, cursor and selection positions are shared between collaborators. To disable this:
|
|
|
|
```tsx
|
|
<RealtimeMonaco channel="realtime-monaco-demo" awareness={false} />
|
|
```
|
|
|
|
## Props
|
|
|
|
| Prop | Type | Description |
|
|
| -------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| `channel` | `string` | Unique channel name used to sync editor content between collaborators in the same session. |
|
|
| `language?` | `string` | Monaco [language identifier](https://code.visualstudio.com/docs/languages/identifiers) (e.g. `typescript`, `python`). Defaults to `javascript`. |
|
|
| `height?` | `string \| number` | Height of the editor container. Accepts a pixel number or CSS string (e.g. `"100%"`). Defaults to `550`. |
|
|
| `className?` | `string` | CSS class applied to the editor wrapper element. |
|
|
| `awareness?` | `boolean \| Awareness` | Enables cursor and selection sharing between users. Pass `false` to disable or a custom `Awareness` instance. Defaults to `true`. |
|
|
| `persistence?` | `boolean \| SupabasePersistenceOptions` | Persists editor content to Supabase so it survives page reloads. Pass `true` for defaults or an options object for fine-grained control. |
|
|
| `theme?` | `'light' \| 'dark'` | Color theme for the editor. Maps to Monaco's `light` and `vs-dark` themes. |
|
|
|
|
### SupabasePersistenceOptions
|
|
|
|
| Option | Type | Default | Description |
|
|
| -------------- | -------- | ----------------- | --------------------------------------------------- |
|
|
| `table` | `string` | `'yjs_documents'` | Name of the Postgres table used to store documents. |
|
|
| `schema` | `string` | `'public'` | Schema where the table is located. |
|
|
| `roomColumn` | `string` | `'room'` | Column used as the document identifier. |
|
|
| `stateColumn` | `string` | `'state'` | Column used to store the binary Yjs state. |
|
|
| `storeTimeout` | `number` | `1000` | Debounce delay (ms) before persisting changes. |
|
|
|
|
## Further reading
|
|
|
|
- [Realtime Broadcast](https://supabase.com/docs/guides/realtime/broadcast)
|
|
- [Realtime authorization](https://supabase.com/docs/guides/realtime/authorization)
|
|
- [`@supabase-labs/y-supabase`](https://github.com/supabase-community/y-supabase)
|
|
- [Yjs documentation](https://docs.yjs.dev/)
|