Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update cloud docs #4247

Merged
merged 1 commit into from
Aug 4, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 89 additions & 53 deletions docs/cloud.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,29 @@
tableOfContents: true
---

"Embed real-time collaboration into your app in under one minute, and everything is in sync." ([Live-Demo](/collab))- If that sounds interesting to you, we might have something :)

# Tiptap Collab

Tiptap Collab is our hosted solution of Hocuspocus (The plug’n’play collaborative editing backend) making it a blast to add real-time collaboration to any app.
Implementing real-time collaboration is quite hard. With Tiptap Collab we build a solution that does it in minutes. To see it in action check out our [live demo](https://tiptap.dev/editor).

Tiptap Collab is our managed cloud solution of [Hocuspocus](https://tiptap.dev/hocuspocus/introduction). It makes it a easy to add real-time collaboration to any application. If you already have an application using Tiptap Editor, it's even easier to add collaboration.

:::warning Pro Feature
To get started, you need a Tiptap Pro account ([sign up / login here](https://tiptap.dev/pro)).
To get started, you need a Tiptap Pro account. [Log in](https://tiptap.dev/login) or [sign up](https://tiptap.dev/register) for free.
:::

[![Cloud Dashboard](https://tiptap.dev/images/docs/server/cloud/dashboard.png)](https://tiptap.dev/images/docs/server/cloud/dashboard.png)
## Getting Started

Note that you need `@hocuspocus/provider` [~v2.0.0](https://github.com/ueberdosis/hocuspocus/releases/tag/v2.0.0)
### Installation

First you need to install `@hocuspocus/provider` at least in version `2.0.0`.

## Getting started
```bash
npm install @hocuspocus/provider
```

Tiptap Collab makes your app collaborative by syncing your Y.Doc across users using websockets. If you are already using yjs in your app, getting started is as simple as shown below.
### Basic Usage

If you are not, you might want to start in our [Tutorials](/tutorials) section.
Tiptap Collab makes your application collaborative by synchronizing a Yjs document between connected users using websockets. If you're already using Yjs in your application, it's as easy as this:

```typescript
import { TiptapCollabProvider } from '@hocuspocus/provider'
Expand All @@ -33,52 +36,57 @@ const provider = new TiptapCollabProvider({
token: 'your_JWT', // see "Authentication" below
doc: new Y.Doc() // pass your existing doc, or leave this out and use provider.document
});

// That's it! Your Y.Doc will now be synced to any other user currently connected
```

### Upgrade from self-hosted deployments

If you are upgrading from a self-hosted deployment, on the frontend you just need to replace `HocuspocusProvider` with the new `TiptapCollabProvider`. The API is the same, it's just a wrapper that handles hostnames / auth.
### Upgrade From Hocuspocus

## Examples
If you are upgrading from our self-hosted collaboration backend called Hocuspocus, all you need to do is replace `HocuspocusProvider` with the new `TiptapCollabProvider`. The API is the same, it's just a wrapper that handles the hostname to your Tiptap Collab app and authentication.

##### replit / Sandbox: Fully functional prototype
## Example

[![Cloud Documents](https://tiptap.dev/images/docs/server/cloud/tiptapcollab-demo.png)](https://tiptap.dev/images/docs/server/cloud/tiptapcollab-demo.png)

We have created a simple client / server setup using replit, which you can review and fork here:
We have created a simple client / server setup using replit that you can review and fork here:

[Github](https://github.com/janthurau/TiptapCollab) or [Replit Demo](https://replit.com/@ueberdosis/TiptapCollab?v=1)

The example loads multiple documents over the same websocket (multiplexing), and shows how to implement per-document authentication using JWT.

[Github](https://github.com/janthurau/TiptapCollab) or [Replit (Live-Demo)](https://replit.com/@ueberdosis/TiptapCollab?v=1)
More tutorials can be found in our [Tutorials section](/tutorials).

The example load multiple documents over the same websocket (multiplexing), and shows how to realize per-document authentication using JWT.
## Authentication

##### Authentication
Authentication is done using [JSON Web Token (JWT)](https://en.wikipedia.org/wiki/JSON_Web_Token). There are many libraries available to generate a valid token.

Authentication is done using JWT. You can see your secret in the admin interface and use it to generate tokens for your clients. If you want to generate a JWT and add some attributes for testing, you can use http://jwtbuilder.jamiekurtz.com/ . You can leave all fields default, just replace the "key" with the secret from your settings.
### JWT Generation

To generate a JWT in the browser, you can use [http://jwtbuilder.jamiekurtz.com/](http://jwtbuilder.jamiekurtz.com/). You can leave all the fields as default, just replace the "Key" at the bottom with the secret from your [settings](https://collab.tiptap.dev/apps/settings).

In Node.js, you can generate a JWT like this:

```typescript
import jsonwebtoken from 'jsonwebtoken'

const data = {
// use this list to limit the number of documents that can be accessed by this client.
// empty array means no access at all
// not sending this property means access to all documents
// we are supporting a wildcard at the end of the string (only there)
// Use this list to limit the number of documents that can be accessed by this client.
// An empty array means no access at all.
// Not sending this property means access to all documents.
// We are supporting a wildcard at the end of the string (only there).
allowedDocumentNames: ['document-1', 'document-2', 'my-user-uuid/*', 'my-organization-uuid/*']
}

// This JWT should be sent in the `token` field of the provider. Never expose 'your_secret' to a frontend!
const jwt = jsonwebtoken.sign(data, 'your_secret')
// this JWT should be sent in the `token` field of the provider. Never expose 'your_secret' to a frontend!
```

#### Getting the JSON document
## Webhook

You can define a URL and we will call it every time a document has changed. This is useful for getting the JSON representation of the Yjs document in your own application. We call your webhook URL when the document is saved to our database. This operation is debounced by 2-10 seconds. So your application won't be flooded by us. Right now we're only exporting the fragment `default` of the Yjs document.
You can add the webhook URL in the [settings page](https://collab.tiptap.dev/apps/settings) of your Tiptap Collab app.

If you want to access the JSON representation (we're currently exporting the `default` fragment of the YDoc), you can add a webhook in the admin interface. We are calling it when storing to our database, so it's debounced by 2 seconds (max 10 seconds).
### Payload

All requests contain a header `X-Hocuspocus-Signature-256` which signs the entire message using 'your_secret' (find it in the settings). The payload looks like this:
A sample payload of the webhook request looks like this:

```json
{
Expand All @@ -91,68 +99,96 @@ All requests contain a header `X-Hocuspocus-Signature-256` which signs the entir
}
```

### Signing

All requests to your webhook URL will contain a header called `X-Hocuspocus-Signature-256` that signs the entire message with your secret. You can find it in the [settings](https://collab.tiptap.dev/apps/settings) of your Tiptap Collab app.

## API
## Management API

Each Tiptap Collab instance comes with an API for the most common operations. Is is provided directly by your Tiptap Collab instance, so it's available under your custom URL:
In addition to the websocket protocol, each Tiptap Collab app comes with a REST API for managing your documents. It's exposed directly from your Tiptap Collab app, so it's available at your custom URL:

`https://YOUR_APP_ID.collab.tiptap.cloud/`

Authentication is done using an admin secret which you can find in your collab [settings area](https://collab.tiptap.dev/). The secret has to be sent as an `Authorization` header.
If your document identifier contains a slash (`/`), just make sure that you encode it as `%2F` (e.g. using javascripts `encodeURIComponent`).
Authentication is done using an API secret which you can find in the [settings](https://collab.tiptap.dev/) of your Tiptap Collab app. The secret must be sent as an `Authorization` header.

### POST /api/documents/:identifier
If your document identifier contains a slash (`/`), just make sure to encode it as `%2F`, e.g. using `encodeURIComponent` of vanilla JavaScript.

This call takes a binary yjs update message (an existing Ydoc on your side must be encoded using `Y.encodeStateAsUpdate`) and creates a document. This can be used to seed documents before a user connects to the Tiptap Collab server.
### Create Document

```bash
POST /api/documents/:identifier
```

This call takes a binary Yjs update message (an existing Yjs document on your side must be encoded using `Y.encodeStateAsUpdate`) and creates a document. This can be used to seed documents before a user connects to the Tiptap Collab server.

This endpoint will return the HTTP status `204` if the document was created successfully, or `409` if the document already exists. If you want to overwrite it, you must delete it first.

```bash
curl --location 'https://YOUR_APP_ID.collab.tiptap.cloud/api/documents/DOCUMENT_NAME' \
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA' \
--data '@yjsUpdate.binary.txt'

// returns either http status 204 if the document was created successfully
// or http status 409 if the document already exists (if you wish to overwrite it, just delete it first)
```

### GET /api/documents/:identifier?format=:format&fragment=:fragment
### Get Document

This call exports the given document (all fragments) in json format. We are exporting either the current in-memory version (in case the document is currently open on your server, or we fetch the most recent version from the database).
```bash
GET /api/documents/:identifier?format=:format&fragment=:fragment
```

This call exports the given document with all fragments in JSON format. We export either the current in-memory version or the version read from the database. If the document is currently open on your server, we will return the in-memory version.

`format` supports either `yjs` or `json`, default=`json`
`format` supports either `yjs` or `json`. Default: `json`

If you choose the `yjs` format, you'll get the binary Y.js update message (created using `Y.encodeStateAsUpdate`)
If you choose the `yjs` format, you'll get the binary Yjs update message created with `Y.encodeStateAsUpdate`.

`fragment` can be an array of (`fragment=a&fragment=b`) or a single fragment that you want exported. By default we're exporting all fragments. Note that this is only considered when using `json` format, otherwise you'll always get the entire Y.doc.
`fragment` can be an array (`fragment=a&fragment=b`) of or a single fragment that you want to export. By default we'll export all fragments. Note that this is only taken into account when using the `json` format, otherwise you'll always get the whole Yjs document.

```bash
curl --location 'https://YOUR_APP_ID.collab.tiptap.cloud/api/documents/DOCUMENT_NAME' \
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA'
```

### Delete Document

// returns either http status 200 and the requested document
// or http status 404 if the document was not found
```bash
DELETE /api/documents/:identifier
```

### DELETE /api/documents/:identifier
This endpoint deletes a document from the server after closing any open connection to the document.

This simply deletes a document from the server after terminating any open connection to the document.
It returns either HTTP status `204` if the document was deleted successfully or `404` if the document was not found.

```bash
curl --location --request DELETE 'https://YOUR_APP_ID.collab.tiptap.cloud/api/documents/DOCUMENT_NAME' \
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA'

// returns either http status 204 if the document was deleted successfully
// or http status 404 if the document was not found
```

### ANY /api/
## Screenshots

Need something else? Hit us up and we'll see what we can do (links below)
Here are some screenshots of Tiptap Collab to give you an idea what of Tiptap Collab looks like.

### Dashboard

## Screenshots
View key metrics such as total or concurrent connections of your Tiptap Collab app.

[![Cloud Dashboard](https://tiptap.dev/images/docs/server/cloud/dashboard.png)](https://tiptap.dev/images/docs/server/cloud/dashboard.png)

### Documents

Get insight into all your documents, such as size or delete them if you want.

[![Cloud Documents](https://tiptap.dev/images/docs/server/cloud/documents.png)](https://tiptap.dev/images/docs/server/cloud/documents.png)

### Logging

View real-time log events for information about currently loaded or modified documents.

[![Cloud Settings](https://tiptap.dev/images/docs/server/cloud/logging.png)](https://tiptap.dev/images/docs/server/cloud/logging.png)

### Settings

Manage the authentication of your application or defined webhooks in the settings.

[![Cloud Settings](https://tiptap.dev/images/docs/server/cloud/settings.png)](https://tiptap.dev/images/docs/server/cloud/settings.png)

## Need anything else?
Expand Down