API

Everything the package exports, and everything it does that can surprise you.

The middleware

edityy({ tag, nonce, root, save, allowedHosts }) // returns a (req, res, next) middleware
  • tag defaults to <script src="/__edityy/edityy.js" defer></script>. Pass your own if you need a different attribute set.
  • nonce adds a nonce to the tag, for a page with a strict script-src CSP. Give a string, or a function (req, res) => string when your app makes a new nonce for each response.
  • root is where .edityy/changes.json is written. It defaults to process.cwd().
  • save: false turns off the save endpoint and the variation endpoint.
  • allowedHosts names more hosts the save endpoint takes, besides localhost and IP addresses. A leading dot also takes the subdomains. true takes every host.

The Vite plugin takes the same options, and adds one of its own: source: false turns off the data-edityy-src attribute.

The exports

  • launcher is the launcher script, as a string.
  • ASSET_PATH is /__edityy/edityy.js, and TAG is the default script tag.
  • inject(body, tag?) injects the tag into an HTML string yourself.
  • changesRoute({ root, allowedHosts }) is the save endpoint as a fetch-style route handler.
  • variationsRoute({ root, allowedHosts }) is the variation endpoint as GET, POST and DELETE route handlers.
  • writeChanges(payload, root?) writes the changes file yourself.
  • CHANGES_PATH and CHANGES_FILE are the endpoint path and the file name.
  • edityy/client is the browser bootstrap that mounts the launcher, for frameworks that inject client modules.
  • edityy/inject is the main module under a second name, for frameworks that render the script tag themselves.
  • edityy/vite is the Vite plugin.

The events

edityy:launcher-click is dispatched on window each time the launcher is clicked, for a host app that wants to know.

The known limits

  • Dev-only. This is not a proxy and not a production server plugin. Install it as a dev dependency and keep it out of your production build.
  • Streamed HTML is held only up to </head>. A chunked response gets the tag before </head>, and everything after it streams through. If no </head> arrives in the first 256 KB, the page is sent unchanged.
  • A strict script-src CSP blocks the tag unless you pass the page's nonce as nonce.
  • Google Fonts need network access. A page whose CSP blocks api.fontsource.org, fonts.googleapis.com or fonts.gstatic.com shows only its own fonts.
  • It fails open. An error inside the middleware is swallowed, and your page is served unchanged, rather than taking the dev server down.

The command

terminal

edityy mcp [--root <dir>]

The command has one subcommand. mcp serves the saved edits to a coding agent over MCP, on stdio.