Skip to content

Early-bird lifetime licence: $199 once, for the first 200 buyers only. See the offer

All docs

Editor app extensions (JavaScript)

The editor app is a React app built on WordPress's own React and wp.hooks. Snipfire Pro adds its part of the editor through the extension points below; you can use them for your own add-on.

Register at load time, before the app first renders: enqueue your script on the snipfire_before_app_script action (see PHP hooks), with wp-hooks and wp-element as dependencies.

wp.hooks.addFilter( 'snipfire.slot.settings.top', 'my-addon', ( fills, props ) => [
    ...fills,
    MyField,
] );

Filters run on every render, so they may read the props they get. Everything on this page is the contract add-ons build against, and is kept stable.

Common props ("ctx")

Passed to slots, filters and views where noted:

Prop What it is
config window.SnipfireApp: restUrl, nonce, schema, siteUrl, toolsUrl, …
pro window.SnipfireApp.pro, or null without Snipfire Pro
access { level, canEdit, canPhp, canImport, canSettings, designHooks }
api REST client: api.request( method, path, body, query ) → Promise (path relative to snipfire/v1/), plus list, get, update, …, and api.url( path, query ) for links
toast toast( 'success' \| 'warning' \| 'error', message )
ask ask( { title, message, input?, confirmLabel, danger } ) → Promise: a confirm dialog
openView openView( name, { value, params } ) opens a registered view (routed as #/name/value?params)
openSnippet openSnippet( id ) opens a snippet (asks about unsaved changes)
startSnippet startSnippet( fields ) opens a new, unsaved snippet with these settings and code ({ type, title, description, hook, priority, code, … }, the fields the server accepts). Asks about unsaved changes first. → Promise of true, or false when the person kept their changes. Snipfire Pro's Write with AI uses it

Component slots

Filter snipfire.slot.<name>, starting value []. Return an array of React components (rendered with the slot's props) or elements. They're rendered in array order, in place.

Slot Where Props
settings.top Top of the settings panel draft, onChange( patch ), readOnly (bool), items, schema, config, pro, access, openSnippet
settings.afterWhere After How it runs / Where / Priority / Shortcode, before Load as same
settings.customHook Under the custom hook name field same
settings.where Under Where (and the paragraph or post number), before Priority, while the snippet runs automatically: the details of a location (Snipfire Pro's CSS selector) same
settings.bottom After Conditions same
editor.toolbar In the editor's toolbar, before History and ⋯ (Snipfire Pro's AI assistant button) draft, dirty, busy, problems, readOnly (reason text or null), onChange( patch ), config, pro, access, api, toast, ask, …
editor.banners Under the toolbar, after the read-only banner, before the error banner draft, dirty, busy, problems, readOnly (reason text or null), onChange( patch ), save( patch? ) → Promise (merges the patch, then saves), config, pro, access, api, toast
editor.side Beside the code editor, on the right (Snipfire Pro's live preview and AI panel). Hidden with the code while the Settings form tab is shown draft, problems, readOnly, theme, onChange( patch ), config, pro, access, api, toast
sidebar.itemBadges In each sidebar item, after the title item (snippet settings, no code), config, pro
sidebar.afterList In the sidebar, under the list of snippets (Snipfire Pro's From the network) ctx + selectedId

problems is what the Problems panel shows: { errors: [ { message, line } ], warnings: [ "…" ] }. draft.error is the error recorded when the snippet last crashed ({ message, line } or null).

Long snippet lists are drawn a screenful at a time (over 400 rows), so don't rely on every row being in the page; sidebar.itemBadges rows re-render when their item, the selection or the list changes.

Value filters

Filter snipfire.<name>:

Filter Arguments Returns
kinds kinds, { config, pro } The snippet kinds in the type picker and + New, in order: [ { kind, label, type, lang, language, tip } ]. kind is the id in #/new/<kind>; type/lang are what a new snippet gets; language is the Monaco language; tip() returns the hint under the editor
statusFilters filters, { config, pro } Sidebar status chips: [ { key, label, match( item ) } ]
toolbarStatus { label, className }, draft, { config, pro } Text next to the Active switch, and a class for its label (e.g. is-testing)
moreMenu items, ctx + { draft, readOnly } The ⋯ menu: [ { id, label, onClick, danger, disabled } ]. Built-in ids: duplicate, export, export-plugin, minimap, theme, settings, classic, delete
newMenu items, ctx The sidebar's + New menu: [ { id, label, onClick } ]. Built-in ids: the kinds (php, html, css, js, …), generator, folder
bulkActions actions, ctx + { ids, clear() } Extra buttons in the bulk actions bar while snippets are ticked: [ { id, label, onClick } ]. ids are the ticked snippets; clear() unticks them
folderActions actions, ctx + { path, name, ids } Small buttons on a folder's row: [ { id, label, icon, onClick } ] (icon is shown; label is the accessible name and tooltip). ids are the snippets in the folder and its subfolders
sidebarLinks links, ctx Sidebar footer links: [ { id, label, href } \| { id, label, onClick } ]. Built-in ids: tools, library, generators, import, welcome, export, classic
runOptions options, the settings panel's slot props The choices for How it runs (PHP and HTML), in order: [ { value, label } ]. Built-in values: auto, shortcode, manual. A value kept for an add-on that isn't active is shown as needing Snipfire Pro
prefill snippet, params, { config, pro, access } A new snippet opened from a link (#/new/<kind>?title=…&hook=…): return the snippet to start with. params are the link's parameters (strings, unchecked); title, hook and (PHP) code are already applied
views views, { config, pro, access } Extra full-width views: { name: { component, label? } } (label names its tab on narrow screens). The component replaces the editor pane and gets ctx + { route: { value, params }, items, exists( id ), close(), reload() }. Names in use: snippet, new, import, library, generators, welcome, export-plugin, editor
draftChange next, patch, previous Every edit of the draft in the editor: return the draft to keep
historyFieldLabel label, field The name of a setting in the History view

Actions

Action snipfire.<name>:

Action Arguments When
monaco monaco, { formatCode( language, code, options ), emmetCSS, emmetHTML } Monaco has loaded (once, when the first editor opens). Register languages, formatters, Emmet, themes

Screens for another set of snippets

A page that shows the editor app for another set of snippets (Snipfire Pro's network screen uses it) points restUrl at its own routes and can set, in window.SnipfireApp:

Setting What it does
features { library, generators, import, welcome }: false hides that screen and its links (all on by default)
contextLabel Shown next to "Snipfire" at the top of the sidebar, for example Network
toolsUrl, classicUrl '' hides the Tools and classic view links

In PHP, Snipfire\Admin\Admin::render_app( $config ) prints the app with such a config.

Opening the editor pre-filled

Links can open a new snippet with settings filled in:

/wp-admin/admin.php?page=snipfire#/new/html?hook=woocommerce_before_cart&title=Cart%20notice
/wp-admin/admin.php?page=snipfire#/new/php?code=…

The hook finder uses this for Add HTML here and Add PHP on this hook, and the element picker with its own parameters (#/new/html?hook=element:selector&selector=…&insert=…&match=…&post=…), which Snipfire Pro reads with the prefill filter. A link only fills in an unsaved draft; nothing is saved until the person clicks Save.

Something unclear or missing? Tell us