diff --git a/docs/src/demos/Extensions/Image/index.vue b/docs/src/demos/Extensions/Image/index.vue
new file mode 100644
index 00000000..52615a3b
--- /dev/null
+++ b/docs/src/demos/Extensions/Image/index.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
diff --git a/docs/src/docPages/api/extensions/image.md b/docs/src/docPages/api/extensions/image.md
new file mode 100644
index 00000000..e811d826
--- /dev/null
+++ b/docs/src/docPages/api/extensions/image.md
@@ -0,0 +1,16 @@
+# Image
+
+## Installation
+```bash
+# With npm
+npm install @tiptap/extension-image
+
+# Or: With Yarn
+yarn add @tiptap/extension-image
+```
+
+## Source code
+[packages/extension-image/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-image/)
+
+## Usage
+
diff --git a/docs/src/links.yaml b/docs/src/links.yaml
index ce4a8bc9..1b6e7e8d 100644
--- a/docs/src/links.yaml
+++ b/docs/src/links.yaml
@@ -132,6 +132,9 @@
link: /api/extensions/history
- title: HorizontalRule
link: /api/extensions/horizontal-rule
+ - title: Image
+ link: /api/extensions/image
+ draft: true
- title: Italic
link: /api/extensions/italic
- title: Link
@@ -163,6 +166,7 @@
link: /api/extensions/text
- title: Text Align
link: /api/extensions/text-align
+ draft: true
# - title: TodoItem
# link: /api/extensions/todo-item
# draft: true
diff --git a/packages/extension-image/index.ts b/packages/extension-image/index.ts
new file mode 100644
index 00000000..605a4b52
--- /dev/null
+++ b/packages/extension-image/index.ts
@@ -0,0 +1,125 @@
+import { Command, createNode, nodeInputRule } from '@tiptap/core'
+import { Plugin } from 'prosemirror-state'
+
+const IMAGE_INPUT_REGEX = /!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\)/
+
+const Image = createNode({
+ name: 'image',
+
+ inline: true,
+
+ group: 'inline',
+
+ addAttributes() {
+ return {
+ src: {
+ default: null,
+ },
+ alt: {
+ default: null,
+ },
+ title: {
+ default: null,
+ },
+ }
+ },
+
+ parseHTML() {
+ return [
+ {
+ tag: 'img[src]',
+ },
+ ]
+ },
+
+ renderHTML({ attributes }) {
+ return ['img', attributes]
+ },
+
+ addCommands() {
+ return {
+ image: (attrs: any): Command => ({ tr }) => {
+ const { selection } = tr
+ console.log({ selection })
+ // const position = selection.$cursor ? selection.$cursor.pos : selection.$to.pos
+ const position = selection.$anchor ? selection.$anchor.pos : selection.$to.pos
+ const node = this.type.create(attrs)
+ tr.insert(position, node)
+
+ return true
+ },
+ }
+ },
+
+ addInputRules() {
+ return [
+ nodeInputRule(IMAGE_INPUT_REGEX, this.type, match => {
+ const [, alt, src, title] = match
+ return {
+ src,
+ alt,
+ title,
+ }
+ }),
+ ]
+ },
+
+ addProseMirrorPlugins() {
+ return [
+ new Plugin({
+ props: {
+ handleDOMEvents: {
+ drop(view, event) {
+ const hasFiles = event.dataTransfer
+ && event.dataTransfer.files
+ && event.dataTransfer.files.length
+
+ if (!hasFiles) {
+ return false
+ }
+
+ const images = Array
+ // @ts-ignore
+ .from(event.dataTransfer.files)
+ .filter(file => (/image/i).test(file.type))
+
+ if (images.length === 0) {
+ return false
+ }
+
+ event.preventDefault()
+
+ const { schema } = view.state
+ const coordinates = view.posAtCoords({ left: event.clientX, top: event.clientY })
+
+ images.forEach(image => {
+ const reader = new FileReader()
+
+ reader.onload = readerEvent => {
+ const node = schema.nodes.image.create({
+ // @ts-ignore
+ src: readerEvent.target.result,
+ })
+ // @ts-ignore
+ const transaction = view.state.tr.insert(coordinates.pos, node)
+ view.dispatch(transaction)
+ }
+ reader.readAsDataURL(image)
+ })
+
+ return true
+ },
+ },
+ },
+ }),
+ ]
+ },
+})
+
+export default Image
+
+declare module '@tiptap/core/src/Editor' {
+ interface AllExtensions {
+ Image: typeof Image,
+ }
+}
diff --git a/packages/extension-image/package.json b/packages/extension-image/package.json
new file mode 100644
index 00000000..5b017870
--- /dev/null
+++ b/packages/extension-image/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "@tiptap/extension-image",
+ "version": "1.0.0",
+ "source": "index.ts",
+ "main": "dist/tiptap-extension-image.js",
+ "umd:main": "dist/tiptap-extension-image.umd.js",
+ "module": "dist/tiptap-extension-image.mjs",
+ "unpkg": "dist/tiptap-extension-image.js",
+ "jsdelivr": "dist/tiptap-extension-image.js",
+ "files": [
+ "src",
+ "dist"
+ ],
+ "peerDependencies": {
+ "@tiptap/core": "2.x"
+ }
+}