The Toolbar Render API uses filter hooks similar to the Dashboard Cards API and Sidebar Render API, allowing plugins to register components that will be rendered in specific locations within the toolbar. Components can be written in either Vue.js or React, with automatic integration via veaury.
uixpress/toolbar/render/left - Components rendered on the left side (before logo/WpToolBar)uixpress/toolbar/render/right - Components rendered on the right side (after search, before notifications)Filter Hook - Modifies the components array
addFilter('uixpress/toolbar/render/left', (components) => {
// Modify components array
return components;
}, priority);
addFilter('uixpress/toolbar/render/right', (components) => {
// Modify components array
return components;
}, priority);
components (Array): The current array of component objectspriority (Number, optional): Priority for the filter (default: 10). Lower numbers run first.Returns an array of component objects.
Each component must be an object with the following structure:
{
metadata: {
id: string, // Unique identifier (required)
language: string, // 'vue' or 'react' (optional, default: 'vue')
className: string, // CSS classes to apply (optional)
requires_capabilities: Array, // User capabilities required (optional)
},
component: Component // Vue or React component (required)
}
id (string, required)
my-plugin/toolbar-widget)toolbar-screen-options, toolbar-help, toolbar-view-sitelanguage (string, optional)
'vue' or 'react''vue'className (string, optional)
requires_capabilities (Array, optional)
['manage_options', 'edit_posts']component (Component, required)
The following components are registered by default via the API:
toolbar-screen-options)hide_screenoptions settingtoolbar-help)hide_help_toggle settingtoolbar-view-site)These components can be removed or modified using filter hooks (see examples below).
import { addFilter } from '@/assets/js/functions/HooksSystem.js';
// Or use window.uixpress.addFilter if outside Vue app
import MyToolbarComponent from './my-toolbar-component.vue';
addFilter('uixpress/toolbar/render/right', (components) => {
return [
...components,
{
metadata: {
id: 'my-plugin/toolbar-widget',
language: 'vue',
className: '',
requires_capabilities: ['manage_options'],
},
component: MyToolbarComponent,
},
];
});
import { addFilter } from '@/assets/js/functions/HooksSystem.js';
import MyLeftToolbarComponent from './MyLeftToolbarComponent.jsx';
addFilter('uixpress/toolbar/render/left', (components) => {
return [
...components,
{
metadata: {
id: 'my-plugin/left-toolbar-widget',
language: 'react',
className: 'mr-4',
},
component: MyLeftToolbarComponent,
},
];
});
import { addFilter } from '@/assets/js/functions/HooksSystem.js';
// Remove Screen Options button
addFilter('uixpress/toolbar/render/right', (components) => {
return components.filter(
(component) => component.metadata?.id !== 'toolbar-screen-options'
);
});
// Remove Help button
addFilter('uixpress/toolbar/render/right', (components) => {
return components.filter(
(component) => component.metadata?.id !== 'toolbar-help'
);
});
// Remove View Site button
addFilter('uixpress/toolbar/render/right', (components) => {
return components.filter(
(component) => component.metadata?.id !== 'toolbar-view-site'
);
});
import { addFilter } from '@/assets/js/functions/HooksSystem.js';
// Modify View Site button to add custom class
addFilter('uixpress/toolbar/render/right', (components) => {
return components.map((component) => {
if (component.metadata?.id === 'toolbar-view-site') {
return {
...component,
metadata: {
...component.metadata,
className: 'custom-class',
},
};
}
return component;
});
});
<script setup>
import { defineProps } from 'vue';
import { useAppStore } from '@/store/app/app.js';
import AppButton from '@/components/utility/app-button/index.vue';
import AppIcon from '@/components/utility/icons/index.vue';
const props = defineProps({
appData: Object,
id: String,
className: String,
});
const appStore = useAppStore();
const handleClick = () => {
// Your custom action
console.log('Toolbar button clicked');
};
</script>
<template>
<AppButton
type="transparent"
:title="__('My Custom Button', 'uixpress')"
@click="handleClick"
:class="className"
>
<AppIcon icon="settings" class="text-xl" />
</AppButton>
</template>
import React from 'react';
/**
* Toolbar React component
* @param {Object} props - Component props
* @param {Object} props.appData - App store instance
* @param {string} props.id - Component ID
* @param {string} props.className - CSS classes
*/
const MyToolbarComponent = ({ appData, id, className }) => {
const handleClick = () => {
// Your custom action
console.log('Toolbar button clicked');
};
return (
<button
onClick={handleClick}
className={`px-3 py-2 rounded hover:bg-zinc-100 dark:hover:bg-zinc-800 ${className || ''}`}
title="My Custom Button"
>
<span className="text-xl">⚙️</span>
</button>
);
};
export default MyToolbarComponent;
import { addFilter } from '@/assets/js/functions/HooksSystem.js';
addFilter('uixpress/toolbar/render/right', (components) => {
const newComponents = [...components];
// Only add component if user has specific capability
if (window.uixpress?.state?.currentUser?.allcaps?.manage_options) {
newComponents.push({
metadata: {
id: 'my-plugin/admin-toolbar-button',
language: 'vue',
requires_capabilities: ['manage_options'],
},
component: AdminOnlyComponent,
});
}
return newComponents;
});
import { addFilter } from '@/assets/js/functions/HooksSystem.js';
// High priority - runs first, adds component at the beginning
addFilter(
'uixpress/toolbar/render/right',
(components) => {
return [
{
metadata: {
id: 'my-plugin/important-button',
language: 'vue',
},
component: ImportantComponent,
},
...components,
];
},
5 // Low priority number = runs first
);
// Low priority - runs last, adds component at the end
addFilter(
'uixpress/toolbar/render/right',
(components) => {
return [
...components,
{
metadata: {
id: 'my-plugin/less-important-button',
language: 'vue',
},
component: LessImportantComponent,
},
];
},
20 // High priority number = runs last
);
Components receive the following props:
appData (Object): The app store instance (Pinia store)id (String): Component ID from metadataclassName (String): CSS classes from metadataappData (Object): The app store instance (Pinia store)id (String): Component ID from metadataclassName (String): CSS classes from metadataThe toolbar component dispatches a custom event when it's ready for plugin registration:
document.addEventListener('uixpress/toolbar/ready', () => {
// Toolbar component is ready, safe to register components
addFilter('uixpress/toolbar/render/right', (components) => {
// Register your components
return components;
});
});
Components registered via uixpress/toolbar/render/left are rendered:
Components registered via uixpress/toolbar/render/right are rendered:
Always prefix your component IDs with your plugin/theme name:
{
metadata: {
id: 'my-plugin/my-toolbar-button', // Good
// Not: 'my-button' // Bad - could conflict with default components
}
}
Follow the design system:
AppButton component for consistencyCheck user capabilities before rendering sensitive content:
{
metadata: {
requires_capabilities: ['manage_options'], // Only admins see this
}
}
Toolbar components should be lightweight and fast-loading:
If supporting both frameworks:
Default components respect uiXpress settings:
hide_screenoptions - Hides Screen Options buttonhide_help_toggle - Hides Help buttondisable_search - Hides Search componentWhen creating custom components, consider similar settings or respect existing ones.
If you're building a WordPress plugin, you can enqueue JavaScript that registers components:
add_action('admin_enqueue_scripts', function() {
wp_enqueue_script(
'my-plugin-toolbar-components',
plugin_dir_url(__FILE__) . 'assets/toolbar-components.js',
['uixpress-app'], // Depend on uiXpress app
'1.0.0',
true
);
});
Then in your JavaScript file:
// Wait for toolbar to be ready
document.addEventListener('uixpress/toolbar/ready', () => {
if (window.uixpress?.addFilter) {
window.uixpress.addFilter('uixpress/toolbar/render/right', (components) => {
return [
...components,
{
metadata: {
id: 'my-plugin/my-toolbar-button',
language: 'vue',
requires_capabilities: ['manage_options'],
},
component: MyComponent, // Imported or defined elsewhere
},
];
});
}
});
addFilter correctlyuixpress/toolbar/ready eventmetadata.language is set to 'react'appData, id, className (camelCase)app-data, id, className (kebab-case)Name: uixpress/toolbar/render/left
Type: Filter
Parameters:
components (Array): Current components arrayReturns: Array of component objects
Priority: Default 10 (lower runs first)
Name: uixpress/toolbar/render/right
Type: Filter
Parameters:
components (Array): Current components arrayReturns: Array of component objects
Priority: Default 10 (lower runs first)
Name: uixpress/toolbar/ready
Type: CustomEvent
When: Dispatched when toolbar component is mounted and ready for plugin registration
Usage: Listen for this event before registering filters
toolbar-screen-options - Screen Options buttontoolbar-help - Help buttontoolbar-view-site - View Site/Dashboard button