What plugins can do
A plugin declares what it needs in a manifest and receives only those capabilities. No direct database access — everything goes through a typed, permission-gated API.
Custom Blocks
Add your own block types to the page builder. Countdown timers, maps, booking widgets — anything React can render.
Dashboard Widgets
Embed custom React widgets directly in the dashboard. Show stats, reports, or quick actions relevant to your workflow.
Custom API Endpoints
Register your own HTTP endpoints under /api/plugins/[name]/. Perfect for webhooks, external integrations, and custom automation.
Sidebar Items
Add your own navigation items to the dashboard sidebar, each linking to a custom route or settings page.
Hooks System
React to CMS events like page:create, page:update, page:load and more. Run logic server-side whenever something happens.
Plugin Storage
Each plugin gets its own isolated key-value storage. Read and write persistent data without touching the main database.
Plugin structure
Every plugin lives in its own folder inside plugins/ and follows a simple, predictable structure.
manifest.json
The heart of every plugin. Declares identity, permissions, contribution points, and config schema. Required fields: name, version, displayName, main, permissions.
- → name (kebab-case, must match folder)
- → version (semver: 1.0.0)
- → permissions (only what you need)
- → contributes (widgets, blocks, routes...)
- → configSchema (user-editable settings)
index.ts
Server-side entry point. Must export an activate(api) function. Receives a capability-based API with only the methods your permissions allow.
- → export function activate(api: PluginAPI)
- → Register hooks via api.hooks.on(...)
- → Return a cleanup function to free resources
- → Can be sync or async
client.tsx
Optional client-side entry point. A React component rendered inside dashboard widgets. Must start with "use client" and export a default component.
- → Receives config + _serverData as props
- → _serverData includes pagesCount, postsCount
- → Wrapped in ErrorBoundary automatically
- → Isolated from other plugins
Optional files
Extend your plugin with additional files as needed.
- → settings.tsx — custom settings page UI
- → blocks/ — custom page builder block components
- → api/ — custom HTTP endpoint handlers
- → README.md — documentation (strongly recommended)
Permissions
Declare only what you need. Each permission unlocks specific API methods — nothing more.
Content
- pages:read — list & read pages
- pages:write — create, update, delete
- posts:read / posts:write
- products:read / products:write
- comments:read / comments:write
- reviews:read / reviews:write
UI
- ui:dashboard — dashboard widgets
- ui:sidebar — sidebar nav items
- ui:blocks — custom page builder blocks
- ui:settings — custom settings pages
- ui:toolbar — toolbar actions
- storage:read / storage:write — media files
System
- network:fetch — external HTTP requests
- site:settings:read — read site config
- site:settings:write — update site config
- analytics:read — block & page analytics
- plugin:storage — isolated key-value store
Minimum privilege principle: declare only the permissions your plugin strictly needs. The API object will only expose methods you're allowed to call.
Security & isolation
Plugins are sandboxed. A broken plugin cannot break WallabyX.
What plugins CAN do
- ✓ Use the typed API within their permissions
- ✓ Register hooks on CMS events
- ✓ Read and write their own isolated storage
- ✓ Render React components in the dashboard
- ✓ Register custom HTTP endpoints
- ✓ Make external HTTP requests (network:fetch)
What plugins CANNOT do
- ✗ Access the database directly
- ✗ Read or write another plugin's storage
- ✗ Modify CMS core files
- ✗ Call API methods without the right permission
- ✗ Block rendering (5s timeout + fail-safe)
- ✗ Crash the CMS (ErrorBoundary on every widget)
Ready to build your first plugin?
Start from the hello-world example included in every WallabyX installation. Full TypeScript, full docs.