File
Handle file pasting, dropping, and uploading in the editor.
It's common to upload files to a remote server when pasting or dropping them into the editor. Here are two approaches to implement this functionality:
Basic Approach: Update After Upload
Section titled “Basic Approach: Update After Upload”The simplest method is to update the document after uploading the file and receiving its URL:
import { insertNode function insertNode(options: InsertNodeOptions): Command
Returns a command that inserts the given node at the current selection or at
the given position. } from 'prosekit/core'
import {
defineFileDropHandler function defineFileDropHandler(handler: FileDropHandler): PlainExtension
,
defineFilePasteHandler function defineFilePasteHandler(handler: FilePasteHandler): PlainExtension
,
} from 'prosekit/extensions/file'
import type { ImageAttrs } from 'prosekit/extensions/image'
import type { Command type Command = (state: EditorState, dispatch?: (tr: Transaction) => void, view?: EditorView) => boolean
Commands are functions that take a state and a an optional
transaction dispatch function and...
- determine whether they apply to this state
- if not, return false
- if `dispatch` was passed, perform their effect, possibly by
passing a transaction to `dispatch`
- return true
In some cases, the editor view is passed as a third argument. } from 'prosekit/pm/state'
import type { EditorView class EditorView
An editor view manages the DOM structure that represents an
editable document. Its state and behavior are determined by its
[props](https://prosemirror.net/docs/ref/#view.DirectEditorProps). } from 'prosekit/pm/view'
async function handleUpload function handleUpload(view: EditorView, file: File, pos?: number): Promise<boolean>
(view view: EditorView
: EditorView class EditorView
An editor view manages the DOM structure that represents an
editable document. Its state and behavior are determined by its
[props](https://prosemirror.net/docs/ref/#view.DirectEditorProps). , file file: File
: File, pos pos: number | undefined
?: number) {
// Upload the file to a remote server and get the URL
const url const url: string
: string = await myUploader function myUploader(file: File): Promise<string>
(file file: File
)
// Attributes for the image node
const attrs const attrs: ImageAttrs
: ImageAttrs = { src ImageAttrs.src?: string | null | undefined
: url const url: string
}
// For paste events, `pos` is undefined. The image node will be
// inserted at the current text cursor position.
// For drop events, `pos` is the drop position. The image node will be
// inserted at the drop position.
const command const command: Command
: Command type Command = (state: EditorState, dispatch?: (tr: Transaction) => void, view?: EditorView) => boolean
Commands are functions that take a state and a an optional
transaction dispatch function and...
- determine whether they apply to this state
- if not, return false
- if `dispatch` was passed, perform their effect, possibly by
passing a transaction to `dispatch`
- return true
In some cases, the editor view is passed as a third argument. = insertNode function insertNode(options: InsertNodeOptions): Command
Returns a command that inserts the given node at the current selection or at
the given position. ({ type InsertNodeOptions.type?: string | NodeType | undefined
The type of the node to insert. Either this or `node` must be provided. : 'image', attrs InsertNodeOptions.attrs?: Attrs | undefined
When `type` is provided, the attributes of the node to insert. , pos InsertNodeOptions.pos?: number | undefined
The position to insert the node at. By default it will be the anchor
position of current selection. })
return command const command: (state: EditorState, dispatch?: (tr: Transaction) => void, view?: EditorView) => boolean
(view view: EditorView
.state EditorView.state: EditorState
The view's current [state](https://prosemirror.net/docs/ref/#state.EditorState). , view view: EditorView
.dispatch EditorView.dispatch: (tr: Transaction) => void
Dispatch a transaction. Will call
[`dispatchTransaction`](https://prosemirror.net/docs/ref/#view.DirectEditorProps.dispatchTransaction)
when given, and otherwise defaults to applying the transaction to
the current state and calling
[`updateState`](https://prosemirror.net/docs/ref/#view.EditorView.updateState) with the result.
This method is bound to the view instance, so that it can be
easily passed around. , view view: EditorView
)
}
const imagePasteExtension const imagePasteExtension: PlainExtension
= defineFilePasteHandler function defineFilePasteHandler(handler: FilePasteHandler): PlainExtension
(({ view view: EditorView
The editor view. , file file: File
The file that was pasted. }) => {
if (!file file: File
The file that was pasted. .type Blob.type: string
The **`type`** read-only property of the Blob interface returns the MIME type of the file.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/type) .startsWith String.startsWith(searchString: string, position?: number): boolean
Returns true if the sequence of elements of searchString converted to a String is the
same as the corresponding elements of this object (converted to a String) starting at
position. Otherwise returns false. ('image/')) return false
void handleUpload function handleUpload(view: EditorView, file: File, pos?: number): Promise<boolean>
(view view: EditorView
The editor view. , file file: File
The file that was pasted. )
return true
})
const imageDropExtension const imageDropExtension: PlainExtension
= defineFileDropHandler function defineFileDropHandler(handler: FileDropHandler): PlainExtension
(({ view view: EditorView
The editor view. , file file: File
The file that was dropped. , pos pos: number
The position of the document where the file was dropped. }) => {
if (!file file: File
The file that was dropped. .type Blob.type: string
The **`type`** read-only property of the Blob interface returns the MIME type of the file.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/type) .startsWith String.startsWith(searchString: string, position?: number): boolean
Returns true if the sequence of elements of searchString converted to a String is the
same as the corresponding elements of this object (converted to a String) starting at
position. Otherwise returns false. ('image/')) return false
void handleUpload function handleUpload(view: EditorView, file: File, pos?: number): Promise<boolean>
(view view: EditorView
The editor view. , file file: File
The file that was dropped. , pos pos: number
The position of the document where the file was dropped. )
return true
})