Plugin API Reference
Purpose: For contributors, provides plugin hooks, registration points, theme API, and component extension points.
Overview
The Headlamp plugin API is exposed through @kinvolk/headlamp-plugin/lib. Plugins import registration functions from this module and call them at the top level of their entry point (src/index.tsx). Headlamp loads each plugin's main.js at startup and executes the registrations before rendering the UI.
Registration Functions
registerAppLogo
Replaces the default Headlamp logo in the sidebar.
import { registerAppLogo } from '@kinvolk/headlamp-plugin/lib';
registerAppLogo(LogoComponent);
Parameters:
| Parameter | Type | Description |
|---|---|---|
LogoComponent | React.ComponentType<AppLogoProps> | React component that renders the logo |
AppLogoProps:
| Prop | Type | Default | Description |
|---|---|---|---|
logoType | 'small' | 'large' | 'large' | 'small' when sidebar is collapsed, 'large' when expanded |
themeName | string | '' | Name of the currently active theme |
Example (from the branding plugin):
import React from 'react';
import type { AppLogoProps } from '@kinvolk/headlamp-plugin/lib';
const AppLogo: React.FC<AppLogoProps> = ({ logoType = 'large', themeName = '' }) => {
const isDark = themeName.toLowerCase().includes('dark')
|| themeName.toLowerCase().includes('night');
const logoSrc = isDark ? '/logo_dark.png' : '/logo.png';
return (
<img
src={logoSrc}
alt="OpenCenter"
style={{
maxHeight: logoType === 'small' ? '32px' : '48px',
padding: '8px',
width: 'auto',
}}
/>
);
};
registerAppTheme
Adds a selectable theme to Settings → Appearance.
import { registerAppTheme } from '@kinvolk/headlamp-plugin/lib';
registerAppTheme(themeDefinition);
Parameters:
| Parameter | Type | Description |
|---|---|---|
themeDefinition | AppTheme | Theme object with name, palette, and component overrides |
AppTheme structure:
interface AppTheme {
name: string; // Display name in the theme dropdown
palette: {
primary: { main: string; contrastText?: string };
secondary: { main: string; contrastText?: string };
background: { default: string; paper: string };
text: { primary: string; secondary: string };
// Additional MUI palette fields supported
};
typography?: object; // MUI typography overrides
components?: object; // MUI component style overrides
}
Multiple themes can be registered. Each call adds one entry to the dropdown. The selected theme persists in browser local storage.
registerRoute
Adds a custom page accessible via URL path.
import { registerRoute } from '@kinvolk/headlamp-plugin/lib';
registerRoute({
path: '/custom-page',
component: () => <CustomPage />,
name: 'custom-page',
sidebar: 'Custom Page',
});
| Field | Type | Description |
|---|---|---|
path | string | URL path for the route |
component | React.ComponentType | React component to render |
name | string | Unique route identifier |
sidebar | string | null | Sidebar label, or null to hide from nav |
registerSidebarEntry
Adds a navigation item to the sidebar without a full route registration.
import { registerSidebarEntry } from '@kinvolk/headlamp-plugin/lib';
registerSidebarEntry({
parent: null,
name: 'my-section',
label: 'My Section',
icon: 'mdi:cog',
url: '/my-section',
});
registerDetailsViewHeaderAction
Adds an action button to the header of resource detail views.
import { registerDetailsViewHeaderAction } from '@kinvolk/headlamp-plugin/lib';
registerDetailsViewHeaderAction(({ item }) => {
if (item.kind !== 'Pod') return null;
return <button onClick={() => handleAction(item)}>Custom Action</button>;
});
Plugin Entry Point Pattern
A plugin's src/index.tsx should call registration functions at the module's top level. Headlamp executes the module once at startup.
// src/index.tsx
import { registerAppLogo, registerAppTheme } from '@kinvolk/headlamp-plugin/lib';
import AppLogo from './components/AppLogo';
import { MyLightTheme, MyDarkTheme } from './theme';
registerAppLogo(AppLogo);
registerAppTheme(MyLightTheme);
registerAppTheme(MyDarkTheme);
Webpack Externals
Plugins must not bundle React or the Headlamp plugin library. These are provided by the host at runtime. The webpack config must declare them as externals:
externals: {
react: 'react',
'react-dom': 'react-dom',
'@kinvolk/headlamp-plugin/lib': '@kinvolk/headlamp-plugin/lib',
}
The output format must be commonjs2:
output: {
filename: 'main.js',
library: { type: 'commonjs2' },
}
Peer Dependency Compatibility
The branding plugin declares these peer dependencies:
| Package | Version Range |
|---|---|
@kinvolk/headlamp-plugin | >=0.7.0 <1.0.0 |
react | ^18.0.0 |
react-dom | ^18.0.0 |
Headlamp versions prior to 0.13.0 do not support registerAppTheme. Logo registration requires at least 0.7.0.
Behaviors and Edge Cases
- If multiple plugins call
registerAppLogo, the last registration wins. - If two themes share the same
name, both appear in the dropdown — avoid name collisions. - Plugins that throw during module execution are silently skipped. Check the browser console for errors.
- Static assets (images, fonts) placed in the plugin's directory are served relative to the plugin path. Use absolute paths from the web root (e.g.,
/logo.png) when assets are copied to the dist root.