withCloud API Reference


Use withCloud to initialize the Slate Editor to add image and file uploading support to Slate.

import { useState } from "react"
import { createEditor } from "slate"
import { withHistory } from "slate-history"
import { withReact } from "slate-react"
import { withCloud } from "slate-cloud"
const [editor] = useState(() => {
const basicEditor = withHistory(withReact(createEditor()))
// ✅ Add `withCloud` plugin on the `Editor` object to enable uploads
const cloudEditor = withCloud(basicEditor, {
apiKey: "MY_API_KEY",
return cloudEditor

The withCloud method takes an Editor object and several options and returns the Editor object with an added editor.cloud property.

type withCloud =
  (editor: Editor, options: WithCloudOptions) =>
    Editor & { cloud: CloudObject } =


Type Definition for Options

type WithCloudOptions = {
  apiKey?: string
  authToken?: string | (() => string) | (() => Promise<string>)
  initialMaxSize?: { width: number; height: number }
  minResizeWidth?: number
  maxResizeWidth?: number
  initialOrigins: Record<string, Origin>
  onUpload: (e: OnUploadEvent) => void

Option Descriptions

  • apiKey?: string | undefined - Pass in a Portive API Key here. If the apiKey is not given, you must give an authToken instead.
  • authToken?: string | (() => string) | (() => Promise<string>) - Pass in an authToken. You can read the Introduction to Autentication to learn how to create one. If an authToken? is not given, an apiKey must be given instead. You can also pass in a function (which can be an async function that returns a Promise) that returns an authToken. This is useful if you want to dynamically generate an authToken on the server. The function can fetch the authToken from an API endpoint before returning the authToken.
  • initialMaxSize: { width: number; height: number } = { width: 320, height: 320} - When an image is uploaded, this sets the initial uploaded image size. By default, the image is resized to fit within a 320x320 bounding box.
  • minResizeWidth?: number = 100 - Images below the minResizeWidth are not shown drag handles for resizing. This is usually a good idea because there is not much value in resizing very small images and the resize handles can overwhelm the size of a small image. Images above the minResizeWidth can be resized, but they can only be resized down to the minResizeWidth.
  • maxResizeWidth?: number = 1280 - The maximum width an image can be resized to.
  • onUpload: (e: OnUploadEvent) => void - When a file upload is started, this onUpload callback is triggered. This is the callback we use to insert our elements into the document. See onUpload below for more information.
  • initialOrigins?: Record<string, Origin> = {} - Used for unit testing. When a file is uploaded, the state of the upload is kept in a zustand store outside of the editor value. This is necessary so that the upload progress is not part of Slate's edit history. During testing, however, we may wish to prepopulate this. NOTE: This will likely be renamed to initialUploads in the near future.


The onUpload callback is called when a user starts a file upload.

If the file is an image, the callback gets called with an OnUploadImageEvent which includes the original dimensions of the image (maxWidth and maxHeight because the image can never be resized beyond its uploaded size) as well as the initialWidth and initialHeight which are the original dimensions of the image constrainted to the initialMaxSize.

If the file is not an image, the callback gets called with an OnUploadGenericEvent.

export type OnUpload = (e: OnUploadEvent) => void

export type OnUploadEvent = OnUploadImageEvent | OnUploadGenericEvent

export type OnUploadImageEvent = {
  type: "image"
  id: string
  initialWidth: number
  initialHeight: number
  maxWidth: number
  maxHeight: number
  file: File

export type OnUploadGenericEvent = {
  type: "generic"
  id: string
  file: File