The core of Local's Add-on API is the Hooks API. This API was heavily inspired by WordPress' Plugin API. If you've written WordPress themes or plugins before, you should feel right at home!
Content Hooks allow you to inject React components into various location in Local's UI. With Content Hooks you can do anything from adding additional buttons, table rows, or even new pages and routes.
Hook Name
Parameters
stylesheets
The following Content Hooks are meant to be used by Environments such as the Preferred and Custom Environment.
ENV_ID and ENV_VERSION are for illustrative purposes only and should be replaced with a static value or variable.
ENV_ID and ENV_VERSION are in the hook name to allow for multiple Environments to be loaded at the same time and to cut down on the number of conditionals required.
SiteInfoDatabase
SiteInfoDatabase_TableList
SiteInfoDatabase_TableList_TableListRow[Connect]:Before
SiteInfoOverview
SiteInfoOverview:Before
SiteInfoOverview_TableList
SiteInfoOverview_TableList:Before
SiteInfo_TabNav_Items
SiteInfo_Top_TopRight
SitesSidebar_SitesSidebarSites:Before
SitesSidebar_SitesSidebarSites
SiteInfoSSL
SiteInfoSSL_TableList
SiteInfoUtilities
SiteInfoUtilities_TableList
routesRoot
Accepts React Router <Route /> components
routes[main]
Accepts React Router <Route /> components
routes[site-info]
Accepts React Router <Route /> components
Hook Name
NewSiteEnvironment[ENV_ID][ENV_VERSION]_AddSiteContent_Inner
SaveBlueprintPage[ENV_ID][ENV_VERSION]_SettingsPane_TableList
SettingsNewSiteDefaults[ENV_ID][ENV_VERSION]
SiteInfoEnvironmentMySQL[ENV_ID][ENV_VERSION]
SiteInfoEnvironmentPHP[ENV_ID:ENV_VERSION]
SiteInfoEnvironmentWebServer[ENV_ID][ENV_VERSION]
hooks.addContent('SiteInfoOverview', (site) => {
return (
<Notes key="notes" site={site} />
);
});hooks.addContent('routesSiteInfo', () => {
return (
<Route
key="site-info-stats"
path="/site-info/:siteID/stats"
component={SiteInfoStats}
/>
);
});sitePlain JavaScript object containing information about the selected site.
Example:
siteStatusString containing one of the following values:
adding
cloning
copying
deleting
container-missing
provisioning-error
wordpress-install-error
pulling-downloading-backup
pulling-importing-backup
pulling-requesting-backup
pushing-packing
pushing-processing
pushing-uploading
{
"id": "BeyQOnaNS",
"localVersion": "3.1.2",
"container": "c61d2aba97ca2306edd42f03275dae0bbda570abe8d93e9ad2ba2a9a93bea895",
"phpVersion": "7.2.9",
"webServer": "nginx",
"mysqlVersion": "5.7",
"multiSite": null,
"mysql": {
"database": "local",
"user": "root",
"password": "root"
},
"ports": {
"HTTP": 4049,
"HTTPS": 4050,
"MYSQL": 4051,
"MAILCATCHER": 4052
},
"flywheelConnect": "flywheel-site-hash",
"environment": "flywheel",
"workspace": null,
"name": "Example Site",
"path": "/Users/username/Local Sites/example-site",
"domain": "example-site.local",
"environmentVersion": "1.3.2",
"sslSHA1": "14f0808d7312bf4031ee198aec75cbd20b8aee2d"
}exporting
exporting-db
halted
provisioning
running
saving
stopping
wordPressInstaller:import
wordPressInstaller:import:includesWP
siteStarted
siteprocesses
siteStopped
siteCloned
siteAdded
siteDeleted
Site id
changeEnvironment:before
searchReplaceWPDatabase
site
oldDomain
newDomain
subSiteURLs
hooks.addAction('siteAdded', function (site) {
console.log('New site added!', site);
});appMenuDescription
Allows you to add or modify items in the main app menu (top bar menu)
Callback Function Parameters
macOS Menu Template
Current Platform provided by process.platform
_____________________________________________________________
Filter Name
Description
Allows you to add menu items to the Site Info More menu inside of a single site view.
Callback Function Parameters
menuItems
Example
_____________________________________________________________
Filter Name
Description
Add-ons have the ability to add items to Local's preferences section by using the preferencesMenuItems filter hook. This filter will add a new item to the left hand column of all Preferences views and allow add-ons to add their own content section.
An AddonSettingsItem object is given to Local via the preferencesMenuItems hook (see usage examples below). This can then render an array of PreferencesSection's or any React component. The latter is provided mainly as an escape hatch in the case that an add-on needs more flexibility. Each PreferencesSection then provides an optional header and a single or array of MenuContentRowItem(s).
Props passed to
<Row />or<Override />components
Callback Function Parameters
preferencesMenu
Examples
"Standard" example passing in sections and sub-headers
Overriding Sections with a single React Component (allows you to render arbitrary things in the "content area")
ENV_ID and ENV_VERSION are for illustrative purposes only and should be replaced with a static value or variable.
Filter Name
Parameters
importBlueprintSiteSettings:ENV_ID:ENV_VERSION
function(menu: MenuTemplate[], platform: string): MenuTemplate[];function(menuItems: SiteInfoMoreMenuItem[], site: Site): SiteInfoMoreMenuItem[];hooks.addFilter('siteInfoMoreMenu', function (menu, site) {
menu.push({
label: 'Volumes',
enabled: !this.context.router.isActive(`/site-info/${site.id}/volumes`),
click: () => {
context.events.send('goToRoute', `/site-info/${site.id}/volumes`);
},
});
return menu;
});{
// React Router props (types are not accurately documented here and developers should reference the React Router documentation for more details)
history: any;
location: any;
match: any;
params: any;
// controls whether or not the "apply" button (rendered by Local) is enabled (clickable) or disabled (not clickable)
setApplyButtonDisabled: (isDisabled: boolean) => void;
// various other props may be passed via Local but are not an offically supported component of this API as of the time of writing
}function(preferencesItem: PreferencesItem[]): PreferencesItem[];const preferenceItem: AddonSettingsItem = {
path: 'image-optimizer',
displayName: 'Image Optimizer',
sections: [
{
// subHeader is optional and if omitted, no subHeader will be rendered
subHeader: 'header 1',
rows: [
{
// this defines what string will be rendered in the left hand "column" of a row
name: 'line 1',
// this defines what will be rendered in the right hand "column" of a row. It can be any React component.
component: Preferences,
},
// ...add some more rows if you want
],
},
// ...add some more sections if you want
],
onApply: () => {
console.log('changes applied!')
},
componentProps: {
// This optional object can be any arbitrary props to get passed to your row components (or Override component)
},
};
hooks.addFilter(
'preferencesMenuItems',
(menu) => {
menu.push(preferenceItem);
// remember to return the menu array here! If you don't Local won't be able to render your Preference item
return menu;
}
);const preferenceItem = {
path: 'image-optimizer',
displayName: 'Image Optimizer',
// this can also just be any old React component. It will be rendered in the Preferences content area
sections: (props) => <div>{props.title}<div/>,
onApply: () => {
console.log('changes applied!')
},
componentProps: {
/* Arbitrary props that will get passed to your row components or section override component. */
/* here we are passing it "title" which will get passed to the "sections" component */
title: 'Preferences Title',
},
}
hooks.addFilter(
'preferencesMenuItems',
(menu) => {
menu.push(preferenceItem);
return menu;
};
);