Add image upload to your Lexical editor in one prompt
Lexical is a contenteditable editor, so it uses PixelVault's upload helper rather than the textarea widget. This prompt wires paste + drop to upload images and insert them as image nodes — no upload backend. Copy it into your AI coding agent.
Claude CodeCursorWindsurfCopilot - 1Copy the prompt
The one big button below.
- 2Paste it into your agent
In your project — Claude Code, Cursor, etc.
- 3Drop in your key
Swap
pv_pub_REPLACE_MEfor a free key. Done.
Add image paste-and-host to my Lexical editor using PixelVault.
Context — read this first and use only the documented API:
- Overview + API: https://pixelvault.dev/llms.txt
- PixelVault upload helper (from @pixelvault-dev/paste):
import { uploadImage } from "@pixelvault-dev/paste";
const { url } = await uploadImage(file, { publishableKey: "pv_pub_REPLACE_ME" });
// returns { id, url, mimeType, size }; throws PixelVaultPasteError on failure
Important: Lexical is a contenteditable editor, not a <textarea>, so do NOT use
the paste-react/usePaste widget here — use uploadImage() directly.
Do this:
1. Install: npm install @pixelvault-dev/paste
2. Make sure my editor has an image node registered. Lexical core ships NO
built-in image node — if my editor doesn't already have one (e.g. the
Lexical playground's ImageNode), STOP and tell me, because I need one before
this can insert images.
3. Register a Lexical handler for pasted/dropped image files. The idiomatic hook
is the DRAG_DROP_PASTE command from @lexical/rich-text:
editor.registerCommand(DRAG_DROP_PASTE, (files) => { ...; return true; }, COMMAND_PRIORITY_LOW)
which fires with the dropped/pasted File(s). For each image file: call
uploadImage(file, { publishableKey }), and on success insert my image node
with the returned url inside an editor.update() block. Don't await inside the
command handler — kick off the async upload and return true. Show a fallback
if the upload throws PixelVaultPasteError.
4. Use my publishable key where I wrote pv_pub_REPLACE_ME (I'll paste my own).
Rules:
- For the PixelVault part, use ONLY uploadImage(file, options) as documented above —
do NOT invent PixelVault endpoints, options, or other packages.
- Use Lexical's own documented commands and my existing image node for the editor
side; if I have no image node, STOP and tell me rather than inventing one.
- Don't block the editor on the upload; insert the node when the URL resolves. What the agent will do
- Install
@pixelvault-dev/paste(core) - Register a
DRAG_DROP_PASTEhandler that uploads viauploadImage() - Insert the returned CDN URL as your Lexical image node
- No backend changes — uploads go straight to PixelVault with your key
Grab your free key
The one thing the agent can't generate is your publishable key (pv_pub_…) — it's origin-scoped and upload-only, safe to ship in browser code. Create one, add your app's origin, and paste it in.
Free tier: 200 MB storage, 500 uploads/mo, 1 GB bandwidth. No card.
How this differs from the textarea prompts
The React, Vue,
and plain-HTML prompts use our drop-in widget, which
attaches to a <textarea>. Lexical renders a contenteditable surface, so the
widget can't attach to it — you upload the file yourself with the lower-level
uploadImage() helper and insert an image node with the returned CDN URL, exactly
like the TipTap and
Quill prompts.
Heads-up: Lexical has no built-in image node
Unlike TipTap, Lexical core ships no image node. This prompt inserts into whatever image node
your editor already has (e.g. the playground's ImageNode) and tells the agent to
stop and flag it if you don't have one — so you won't get code that references a node that
doesn't exist.
The PixelVault part, by hand
Everything editor-specific is standard Lexical. The only PixelVault call is one function:
import { uploadImage } from "@pixelvault-dev/paste";
const { url } = await uploadImage(file, {
publishableKey: "pv_pub_xxxxxxxx",
});
// url → https://img.pixelvault.dev/… (a permanent CDN URL)
// then insert your image node with { src: url } inside editor.update()
Wire that into Lexical's DRAG_DROP_PASTE command (from
@lexical/rich-text), upload each image file, and insert on success. The
docs and llms.txt have the full
reference.
Why a prompt instead of docs?
Because "add image upload to my Lexical editor" is exactly what you'd hand a coding agent — and
it needs to know to use uploadImage() (not a nonexistent widget) and to respect
Lexical's image-node requirement. This prompt grounds the PixelVault call and lets the agent
handle Lexical's commands. Copy, paste, ship.
FAQ
How do I add image upload to a Lexical editor?
Copy the prompt above into your AI coding agent. Because Lexical is contenteditable (not a textarea), it uses PixelVault's uploadImage() helper inside Lexical's DRAG_DROP_PASTE command, then inserts the returned CDN URL as your image node.
Does Lexical have a built-in image node?
No — Lexical core ships no image node. You need one registered (for example the Lexical playground's ImageNode) before images can be inserted. The prompt tells the agent to stop and flag this if your editor doesn't have one.
Do I need an upload backend for Lexical image uploads?
No. uploadImage() sends the file straight from the browser to PixelVault with an origin-scoped, upload-only publishable key. There's no server route to build.