Copy to Webflow / Paste from Webflow as a reusable npm library. Put Xscp JSON on the clipboard in the format Webflow Designer expects (so users can Cmd+V in Designer), or extract Xscp from a paste event.
Use the core API in any JS/TS app, or the React components for a ready "Copy to Webflow" button.
- Source code: https://github.com/bejamas/webflow-clipboard
- Issues: https://github.com/bejamas/webflow-clipboard/issues
npm install webflow-clipboard
# or
bun add webflow-clipboard
# or
pnpm add webflow-clipboardimport { CopyToWebflowButton } from "webflow-clipboard/react";
// Your Xscp JSON (e.g. from your CMS, Git, or "Paste from Webflow")
const xscpJson = '{"type":"@webflow/XscpData","payload":{...}}';
export function MyComponent() {
return (
<CopyToWebflowButton
xscpJson={xscpJson}
className="rounded-full bg-black text-white px-4 py-2"
showMessage
/>
);
}On click, the button copies the JSON to the clipboard so the user can open Webflow Designer and press Cmd+V (Mac) or Ctrl+V (Windows).
Use in any environment (Node scripts, vanilla JS, other frameworks):
import {
writeClipboardXscp,
normalizeXscp,
validateCopyPayload,
getXscpFromPasteEvent,
} from "webflow-clipboard";
// Copy Xscp to clipboard (must run in a user gesture / browser context)
writeClipboardXscp(xscpJsonString);
// Normalize / validate before copy
const result = validateCopyPayload(rawString);
if (result.valid) {
writeClipboardXscp(rawString);
}
// In a paste handler (e.g. onPaste on a contenteditable or textarea)
element.addEventListener("paste", (e) => {
const json = getXscpFromPasteEvent(e);
if (json) {
e.preventDefault();
console.log("Pasted Webflow JSON", json);
}
});Build your own button or trigger copy from code:
import { useCopyToWebflow } from "webflow-clipboard/react";
function MyButton() {
const { copyToWebflow, status, error, successMessage } = useCopyToWebflow({
successMessage: "Copied! Paste in Webflow Designer with Cmd+V.",
});
return (
<div>
<button onClick={() => copyToWebflow(xscpJson)}>Copy to Webflow</button>
{error && <p role="alert">{error}</p>}
{successMessage && <p>{successMessage}</p>}
</div>
);
}Implement a "Paste from Webflow" area (user copies in Designer, pastes in your app):
import { usePasteFromWebflow } from "webflow-clipboard/react";
function PasteArea() {
const { json, onPaste, error, copyJson, copied } = usePasteFromWebflow();
return (
<div>
<textarea
onPaste={onPaste}
value={json}
placeholder="Click here, then Cmd+V (after copying in Webflow Designer)"
readOnly
/>
{error && <p role="alert">{error}</p>}
{json && (
<button onClick={copyJson}>{copied ? "Copied" : "Copy JSON"}</button>
)}
</div>
);
}| Export | Description |
|---|---|
writeClipboardXscp(xscp) |
Copies normalized Xscp to clipboard (both application/json and text/plain) so Webflow Designer accepts Cmd+V. |
normalizeXscp(raw) |
Normalizes raw Xscp string; throws if invalid. |
normalizeCopyPayload(payload) |
Extracts first JSON object from a string (for payloads with junk). |
validateCopyPayload(payload) |
Returns { valid, length } or { valid: false, error, length, tailPreview? }. |
isXscpPayload(payload) |
Returns true if payload looks like Webflow Xscp. |
getXscpFromPasteEvent(e) |
From a ClipboardEvent, returns Xscp string or null. |
| Export | Description |
|---|---|
CopyToWebflowButton |
Button that takes xscpJson and copies on click. |
useCopyToWebflow(options?) |
Hook: copyToWebflow(xscp), status, error, successMessage, reset. |
usePasteFromWebflow() |
Hook: json, onPaste, error, copyJson, copied, reset. |
Webflow Designer only accepts paste when the clipboard has application/json. Browsers don’t allow setting that via navigator.clipboard.write(); this library uses a programmatic copy event to set both application/json and text/plain, so Designer accepts Cmd+V.
For paste from Webflow, Xscp is only exposed on the paste event (not on normal clipboard read), so you need a paste handler; getXscpFromPasteEvent / usePasteFromWebflow do that.
MIT