Skip to main content

Plugin Template Development Guide

This guide provides detailed instructions for customizing and developing your BrainDrive plugin using this template.

🎯 Quick Start Checklist

1. Initial Setup

  • Clone or copy the Plugin Template
  • Update package.json with your plugin details
  • Rename PluginTemplate files to your plugin name
  • Update webpack configuration
  • Customize lifecycle manager metadata

2. Development Environment

  • Install dependencies: npm install
  • Build the plugin: npm run build
  • Install plugin through BrainDrive Plugin Manager for testing
  • Test functionality within BrainDrive environment

3. Customization

  • Implement your plugin's core functionality
  • Add custom components and services
  • Configure BrainDrive service requirements
  • Style your plugin with custom CSS
  • Test with real BrainDrive services

4. Build and Deploy

  • Build plugin: npm run build
  • Install via BrainDrive Plugin Manager
  • Test functionality in BrainDrive environment

🔧 Detailed Customization Steps

Step 1: Rename and Configure

1.1 Update package.json

{
"name": "your-plugin-name",
"version": "1.0.0",
"description": "Your plugin description",
"author": "Your Name"
}

1.2 Update webpack.config.js

const PLUGIN_NAME = "YourPluginName"; // Change this
const PLUGIN_PORT = 3004; // Change to available port

1.3 Rename Files

# Rename main component files
mv src/PluginTemplate.tsx src/YourPluginName.tsx
mv src/PluginTemplate.css src/YourPluginName.css

# Update imports in index.tsx
# Update component class name
# Update CSS class names

1.4 Update lifecycle_manager.py

self.plugin_data = {
"name": "YourPluginName",
"description": "Your plugin description",
"plugin_slug": "YourPluginName",
"source_url": "https://github.com/YourUsername/YourPluginName",
# ... other metadata
}

Step 2: Implement Core Functionality

2.1 Define Your Data Structure

Update src/types.ts:

// Replace PluginData with your data structure
export interface YourDataType {
id: string;
// Add your specific fields
title: string;
content: string;
status: 'active' | 'inactive';
createdAt: string;
}

2.2 Implement Your Service

Update src/services/PluginService.ts:

export class YourPluginService {
// Implement methods specific to your plugin
async fetchYourData(): Promise<YourDataType[]> {
// Your API calls
}

async processYourData(data: YourDataType): Promise<void> {
// Your business logic
}
}

2.3 Update Main Component

In your main component file:

class YourPluginName extends React.Component<YourProps, YourState> {
// Implement your plugin's UI and logic

private async loadYourData(): Promise<void> {
// Load your specific data
}

private renderYourContent(): JSX.Element {
// Render your plugin's content
}
}

Step 3: Configure BrainDrive Integration

3.1 Service Requirements

In lifecycle_manager.py, specify which BrainDrive services you need:

"required_services": {
"api": {
"methods": ["get", "post", "put", "delete"],
"version": "1.0.0"
},
"theme": {
"methods": ["getCurrentTheme", "addThemeChangeListener"],
"version": "1.0.0"
},
"settings": {
"methods": ["getSetting", "setSetting"],
"version": "1.0.0"
},
# Add other services as needed
}

3.2 Configuration Fields

Define user-configurable options:

"config_fields": {
"api_endpoint": {
"type": "text",
"description": "API endpoint URL",
"default": "https://api.example.com"
},
"refresh_interval": {
"type": "number",
"description": "Refresh interval in seconds",
"default": 60
},
"enable_notifications": {
"type": "boolean",
"description": "Enable notifications",
"default": true
}
}

3.3 Layout Configuration

Set your plugin's layout constraints:

"layout": {
"minWidth": 4,
"minHeight": 3,
"defaultWidth": 8,
"defaultHeight": 6,
"maxWidth": 12,
"maxHeight": 12
}

Step 4: Custom Components

4.1 Create Custom Components

// src/components/YourCustomComponent.tsx
import React from 'react';

interface YourCustomComponentProps {
data: YourDataType;
onAction: (action: string) => void;
}

const YourCustomComponent: React.FC<YourCustomComponentProps> = ({
data,
onAction
}) => {
return (
<div className="your-custom-component">
{/* Your component JSX */}
</div>
);
};

export default YourCustomComponent;

4.2 Export Components

Update src/components/index.ts:

export { default as YourCustomComponent } from './YourCustomComponent';
export { default as LoadingSpinner } from './LoadingSpinner';
export { default as ErrorDisplay } from './ErrorDisplay';

Step 5: Styling

5.1 CSS Variables

Use CSS variables for theme support:

:root {
--your-plugin-primary: #007bff;
--your-plugin-secondary: #6c757d;
/* Add your color scheme */
}

.your-plugin--dark {
--your-plugin-primary: #4dabf7;
--your-plugin-secondary: #b0b0b0;
/* Dark theme colors */
}

5.2 Component Styles

.your-plugin {
background-color: var(--plugin-bg-primary);
color: var(--plugin-text-primary);
/* Use template variables or create your own */
}

.your-custom-component {
/* Your component styles */
}

Step 6: API Integration

6.1 Using BrainDrive API Service

// In your component
private async fetchDataFromAPI(): Promise<void> {
const { services } = this.props;

if (!services.api) {
throw new Error('API service not available');
}

try {
const response = await services.api.get('/your-endpoint');
this.setState({ data: response.data });
} catch (error) {
this.setState({ error: 'Failed to fetch data' });
}
}

6.2 Handling Settings

private async loadSettings(): Promise<void> {
const { services } = this.props;

if (services.settings) {
const apiEndpoint = await services.settings.getSetting('api_endpoint');
const refreshInterval = await services.settings.getSetting('refresh_interval');

// Use settings in your plugin
}
}

Step 7: Error Handling

7.1 Component Error Boundaries

componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
console.error('Plugin error:', error, errorInfo);
this.setState({
error: 'An unexpected error occurred',
hasError: true
});
}

7.2 Service Error Handling

private async safeApiCall<T>(
apiCall: () => Promise<T>,
fallback: T
): Promise<T> {
try {
return await apiCall();
} catch (error) {
console.error('API call failed:', error);
return fallback;
}
}

Step 8: Testing

8.1 Development Testing

# Build the plugin
npm run build

# Install via BrainDrive Plugin Manager
# Test functionality within BrainDrive
# Verify service integration works
# Check responsive design

8.2 Build Testing

# Build plugin
npm run build

# Check bundle size
ls -la dist/remoteEntry.js

# Verify bundle was created successfully

8.3 Integration Testing

# Test with BrainDrive
python3 lifecycle_manager.py metadata

# Install in BrainDrive development environment
# Test all functionality
# Verify service integration

🚀 Advanced Features

Streaming API Support

// Using streaming API
if (services.api?.postStreaming) {
await services.api.postStreaming(
'/streaming-endpoint',
{ query: 'your query' },
(chunk) => {
// Handle streaming response
this.handleStreamingChunk(chunk);
}
);
}

Event Communication

// Send events to other plugins
services.event?.sendMessage('other-plugin', {
type: 'data-update',
data: yourData
});

// Listen for events
services.event?.subscribeToMessages('your-plugin', (message) => {
this.handleIncomingMessage(message);
});

Page Context Awareness

// React to page changes
if (services.pageContext) {
this.pageContextUnsubscribe = services.pageContext.onPageContextChange((context) => {
if (context.isStudioPage) {
// Adapt behavior for studio page
}
});
}

📋 Best Practices

1. Performance

  • Use React.memo for expensive components
  • Implement proper cleanup in componentWillUnmount
  • Debounce expensive operations
  • Use lazy loading for large components

2. Accessibility

  • Use semantic HTML elements
  • Add proper ARIA labels
  • Ensure keyboard navigation works
  • Test with screen readers

3. Responsive Design

  • Use CSS Grid and Flexbox
  • Test on different screen sizes
  • Consider mobile-first approach
  • Use relative units (rem, em, %)

4. Error Handling

  • Always handle async operation failures
  • Provide user-friendly error messages
  • Log errors for debugging
  • Implement retry mechanisms

5. Code Organization

  • Keep components small and focused
  • Separate business logic into services
  • Use TypeScript for type safety
  • Follow consistent naming conventions

🐛 Common Issues

TypeScript Errors

# Install missing types
npm install --save-dev @types/node

# Check tsconfig.json configuration
# Verify import paths

Build Failures

# Clear node_modules and reinstall
rm -rf node_modules package-lock.json
npm install

# Check webpack configuration
# Verify all imports are correct

Runtime Errors

# Check browser console
# Verify service availability
# Test with mock services first
# Check network requests

📚 Additional Resources


Happy coding! 🚀