Table of Contents
- Introduction
- Prerequisites
- Understanding the Architecture
- Step-by-Step Plugin Creation
- Advanced Features
- Testing and Debugging
- Deployment
- Troubleshooting
- Resources
Introduction
What is an OpenSearch Dashboards Plugin?
An OpenSearch Dashboards plugin is a modular extension that adds custom functionality to your OpenSearch Dashboards installation. Plugins can:
- Create new visualizations and dashboards
- Add custom data sources
- Implement specialized search interfaces
- Integrate external services
- Extend existing functionality
Why Create a Plugin?
Create a plugin when you need to:
- Customize the user interface beyond standard configurations
- Add business-specific features not available in core OpenSearch
- Integrate third-party services or APIs
- Create reusable components across multiple dashboards
- Implement specialized data processing or analytics
About This Guide
For more insights and to explore my other repositories or access this post in Portuguese, be sure to visit my GitHub profile at my GitHub.
Prerequisites
Before you begin, ensure you have:
Required Software
| Software | Minimum Version | Purpose |
|---|---|---|
| Node.js | 14.x or higher | Runtime environment |
| Yarn | 1.22.x | Package manager |
| Git | 2.x | Version control |
| Code Editor | Any | VS Code recommended |
- Note: minimum version requirements may vary depending on the OpenSearch Dashboards version in use. Always check the official documentation for the target release to ensure full compatibility of the development environment. The example above is based on OpenSearch Dashboards version 2.11.
Required Knowledge
- JavaScript/TypeScript: Basic to intermediate level
- React: Understanding of components and hooks
- REST APIs: How to create and consume APIs
- Command Line: Basic terminal/command prompt usage
Verify Your Setup
Run these commands to verify your environment:
# Check Node.js version
node --version
# Should output: v14.x.x or higher
# Check Yarn version
yarn --version
# Should output: 1.22.x or higher
# Check Git version
git --version
# Should output: 2.x.x or higher
Understanding the Architecture
Plugin Structure Overview
Before diving into code, let's understand how OpenSearch Dashboards plugins are organized:
my-plugin-name/
│
├── opensearch_dashboards.json # Plugin metadata and dependencies
├── package.json # NPM package configuration
├── tsconfig.json # TypeScript configuration
│
├── public/ # Client-side code (runs in browser)
│ ├── index.ts # Public plugin entry point
│ ├── plugin.ts # Main plugin class
│ ├── application.tsx # React app initialization
│ ├── components/ # React components
│ │ └── app.tsx # Main app component
│ └── types.ts # TypeScript type definitions
│
└── server/ # Server-side code (runs on backend)
├── index.ts # Server plugin entry point
├── plugin.ts # Server plugin class
├── routes/ # API route definitions
└── types.ts # Server-side types
Key Concepts
1. Plugin Lifecycle
Plugins follow a specific lifecycle:
- Initialization: Plugin is loaded and initialized
- Setup: Dependencies are configured, routes registered
- Start: Plugin becomes active and functional
- Stop: Cleanup when plugin is disabled
2. Client-Server Architecture
- Public (Client): Handles UI, user interactions, browser-side logic
- Server: Manages API endpoints, data processing, OpenSearch communication
3. Core Services
OpenSearch Dashboards provides core services:
- HTTP: Create API routes and make requests
- Notifications: Display toast messages and alerts
- SavedObjects: Store and retrieve plugin data
- Application: Register and navigate between apps
Step-by-Step Plugin Creation
Step 1: Set Up Your Development Environment
1.1 Clone OpenSearch Dashboards Repository
# Clone the repository
git clone https://github.com/opensearch-project/OpenSearch-Dashboards.git
# Navigate into the directory
cd OpenSearch-Dashboards
# Checkout the version you're targeting (e.g., 2.11)
git checkout 2.11
Why? You need the OpenSearch Dashboards source code to develop and test plugins locally.
1.2 Install Dependencies
# Install all dependencies (this may take 10-15 minutes)
yarn osd bootstrap
What does this do?
- Installs all required packages
- Links dependencies between plugins
- Prepares the development environment
⏱️ Grab a coffee! This process takes time but only needs to be done once.
Step 2: Generate Your Plugin
2.1 Use the Plugin Generator
# Run the generator from the OpenSearch Dashboards root directory
node scripts/generate_plugin.js my-custom-plugin
# When prompted, answer:
# - Generate a plugin in ./plugins? Yes
# - Would you like to create the plugin in a different folder? No
# - Should your plugin have server-side code? Yes
# - Should your plugin have a UI component? Yes
What just happened?
- A complete plugin scaffold was created in
plugins/my-custom-plugin - All necessary files and folders were generated
- Basic TypeScript configurations were set up
2.2 Navigate to Your Plugin
cd plugins/my-custom-plugin
Step 3: Configure Plugin Metadata
3.1 Understanding opensearch_dashboards.json
Open opensearch_dashboards.json and update it:
{
"id": "myCustomPlugin",
"version": "1.0.0",
"opensearchDashboardsVersion": "2.11.0",
"server": true,
"ui": true,
"requiredPlugins": ["data"],
"optionalPlugins": ["visualizations"],
"requiredBundles": []
}
Field Explanations:
-
id: Unique identifier (camelCase, no spaces) -
version: Your plugin version (follows semantic versioning) -
opensearchDashboardsVersion: Compatible OSD version -
server: Set totrueif plugin has backend code -
ui: Set totrueif plugin has frontend UI -
requiredPlugins: Plugins that MUST be installed -
optionalPlugins: Plugins that enhance functionality if available
3.2 Configure package.json
{
"name": "my-custom-plugin",
"version": "1.0.0",
"description": "A custom plugin for OpenSearch Dashboards",
"main": "target/my-custom-plugin",
"opensearchDashboards": {
"version": "2.11.0",
"templateVersion": "1.0.0"
},
"scripts": {
"build": "yarn plugin-helpers build",
"plugin-helpers": "node ../../scripts/plugin_helpers"
},
"devDependencies": {
"@types/react": "^17.0.3"
}
}
Step 4: Build the Client-Side (Frontend)
4.1 Create the Plugin Class (public/plugin.ts)
import { CoreSetup, CoreStart, Plugin } from '../../../src/core/public';
// Define what your plugin provides to other plugins during setup
export interface MyCustomPluginSetup {}
// Define what your plugin provides after it starts
export interface MyCustomPluginStart {}
export class MyCustomPlugin implements Plugin<MyCustomPluginSetup, MyCustomPluginStart> {
/**
* Setup is called when the plugin is initialized
* This is where you register your application
*/
public setup(core: CoreSetup) {
// Register the main application
core.application.register({
id: 'myCustomPlugin',
title: 'My Custom Plugin',
// Where the app appears in the navigation
category: {
id: 'customCategory',
label: 'Custom Tools',
order: 1000,
},
// The function that renders your app
mount: async (params) => {
// Lazy load the app component
const { renderApp } = await import('./application');
return renderApp(core, params);
},
});
return {};
}
/**
* Start is called when all plugins are set up
* This is where you can use services from other plugins
*/
public start(core: CoreStart) {
return {};
}
/**
* Stop is called when the plugin is being shut down
* Clean up any resources here
*/
public stop() {
// Cleanup code here
}
}
Key Points:
-
setup(): Runs once during initialization - register your app here -
mount(): Lazy loads your React app for better performance -
start(): Runs after all plugins are ready - use plugin dependencies here
4.2 Create the Entry Point (public/index.ts)
import { PluginInitializerContext } from '../../../src/core/public';
import { MyCustomPlugin } from './plugin';
/**
* This is the entry point for your plugin
* OpenSearch Dashboards calls this function to create your plugin instance
*/
export function plugin(initializerContext: PluginInitializerContext) {
return new MyCustomPlugin();
}
// Export plugin types for other plugins to use
export { MyCustomPluginSetup, MyCustomPluginStart } from './plugin';
4.3 Create the React Application (public/application.tsx)
import React from 'react';
import ReactDOM from 'react-dom';
import { AppMountParameters, CoreStart } from '../../../src/core/public';
import { MyPluginApp } from './components/app';
/**
* Renders the React application into the DOM
* @param core - OpenSearch Dashboards core services
* @param params - Mount parameters including the DOM element
*/
export const renderApp = (
core: CoreStart,
params: AppMountParameters
) => {
// Render the React app
ReactDOM.render(
<MyPluginApp coreStart={core} />,
params.element
);
// Return cleanup function
return () => {
ReactDOM.unmountComponentAtNode(params.element);
};
};
4.4 Create the Main Component (public/components/app.tsx)
import React, { useState } from 'react';
import {
EuiPage,
EuiPageBody,
EuiPageContent,
EuiPageContentBody,
EuiPageHeader,
EuiTitle,
EuiText,
EuiButton,
EuiSpacer,
} from '@elastic/eui';
import { CoreStart } from '../../../../src/core/public';
interface MyPluginAppProps {
coreStart: CoreStart;
}
export const MyPluginApp: React.FC<MyPluginAppProps> = ({ coreStart }) => {
const [counter, setCounter] = useState(0);
const handleClick = () => {
setCounter(counter + 1);
// Show a success toast notification
coreStart.notifications.toasts.addSuccess({
title: 'Button Clicked!',
text: `Counter is now ${counter + 1}`,
});
};
return (
<EuiPage>
<EuiPageBody>
<EuiPageHeader>
<EuiTitle size="l">
<h1>My Custom Plugin</h1>
</EuiTitle>
</EuiPageHeader>
<EuiPageContent>
<EuiPageContentBody>
<EuiText>
<h2>Welcome to Your Custom Plugin!</h2>
<p>
This is a basic plugin template. You can extend it with your own
functionality.
</p>
</EuiText>
<EuiSpacer size="l" />
<EuiText>
<p>Counter: <strong>{counter}</strong></p>
</EuiText>
<EuiSpacer size="m" />
<EuiButton fill onClick={handleClick}>
Increment Counter
</EuiButton>
</EuiPageContentBody>
</EuiPageContent>
</EuiPageBody>
</EuiPage>
);
};
What's happening here?
- Elastic UI (EUI) Components: Using pre-built UI components for consistency
-
State Management: Using React hooks (
useState) for interactivity -
Core Services: Accessing notifications through
coreStart
Step 5: Build the Server-Side (Backend)
5.1 Create the Server Plugin (server/plugin.ts)
import {
CoreSetup,
CoreStart,
Plugin,
Logger,
PluginInitializerContext,
} from '../../../src/core/server';
export class MyCustomPluginServer implements Plugin {
private readonly logger: Logger;
constructor(initializerContext: PluginInitializerContext) {
this.logger = initializerContext.logger.get();
}
public setup(core: CoreSetup) {
this.logger.info('MyCustomPlugin: Setting up');
// Create a router for API endpoints
const router = core.http.createRouter();
// Register a GET endpoint
router.get(
{
path: '/api/my-custom-plugin/hello',
validate: false, // We'll add validation later
},
async (context, request, response) => {
this.logger.info('Hello endpoint called');
return response.ok({
body: {
message: 'Hello from my custom plugin!',
timestamp: new Date().toISOString(),
},
});
}
);
// Register a POST endpoint with data
router.post(
{
path: '/api/my-custom-plugin/data',
validate: {
body: schema.object({
name: schema.string(),
value: schema.number(),
}),
},
},
async (context, request, response) => {
const { name, value } = request.body;
this.logger.info(`Received data: ${name} = ${value}`);
return response.ok({
body: {
success: true,
received: { name, value },
},
});
}
);
return {};
}
public start(core: CoreStart) {
this.logger.info('MyCustomPlugin: Started');
return {};
}
public stop() {
this.logger.info('MyCustomPlugin: Stopping');
}
}
5.2 Add Request Validation (server/plugin.ts - enhanced)
import { schema } from '@osd/config-schema';
// Inside your route definition:
router.get(
{
path: '/api/my-custom-plugin/search',
validate: {
query: schema.object({
term: schema.string({ minLength: 1, maxLength: 100 }),
page: schema.number({ defaultValue: 1, min: 1 }),
size: schema.number({ defaultValue: 10, min: 1, max: 100 }),
}),
},
},
async (context, request, response) => {
const { term, page, size } = request.query;
// Your search logic here
return response.ok({
body: { results: [], total: 0 },
});
}
);
Why validation matters:
- Security: Prevents malicious input
- Data Integrity: Ensures correct data types
- Clear API Contract: Documents expected parameters
5.3 Create Server Entry Point (server/index.ts)
import { PluginInitializerContext } from '../../../src/core/server';
import { MyCustomPluginServer } from './plugin';
export function plugin(initializerContext: PluginInitializerContext) {
return new MyCustomPluginServer(initializerContext);
}
export { MyCustomPluginServer as Plugin };
Step 6: Connect Frontend to Backend
6.1 Create an API Service (public/services/api.ts)
import { HttpSetup } from '../../../../src/core/public';
export class ApiService {
private http: HttpSetup;
constructor(http: HttpSetup) {
this.http = http;
}
/**
* Fetch hello message from the backend
*/
async getHello(): Promise<{ message: string; timestamp: string }> {
try {
const response = await this.http.get('/api/my-custom-plugin/hello');
return response;
} catch (error) {
throw new Error(`Failed to fetch hello: ${error.message}`);
}
}
/**
* Send data to the backend
*/
async sendData(name: string, value: number): Promise<any> {
try {
const response = await this.http.post('/api/my-custom-plugin/data', {
body: JSON.stringify({ name, value }),
});
return response;
} catch (error) {
throw new Error(`Failed to send data: ${error.message}`);
}
}
}
6.2 Use the API in Your Component
// In public/components/app.tsx
import React, { useState, useEffect } from 'react';
import { ApiService } from '../services/api';
export const MyPluginApp: React.FC<MyPluginAppProps> = ({ coreStart }) => {
const [message, setMessage] = useState<string>('');
const [loading, setLoading] = useState<boolean>(true);
useEffect(() => {
const api = new ApiService(coreStart.http);
const fetchData = async () => {
try {
const data = await api.getHello();
setMessage(data.message);
} catch (error) {
coreStart.notifications.toasts.addDanger({
title: 'Error',
text: error.message,
});
} finally {
setLoading(false);
}
};
fetchData();
}, [coreStart]);
if (loading) {
return <div>Loading...</div>;
}
return (
<EuiPage>
{/* Your UI here */}
<EuiText><p>{message}</p></EuiText>
</EuiPage>
);
};
Step 7: Build and Test Your Plugin
7.1 Development Mode
# From the OpenSearch Dashboards root directory
yarn start
# This will:
# - Start the development server
# - Watch for file changes
# - Enable hot reloading
# - Run on http://localhost:5601
Access your plugin:
- Open browser to
http://localhost:5601 - Look for "Custom Tools" in the left sidebar
- Click "My Custom Plugin"
7.2 Build for Production
# Navigate to your plugin directory
cd plugins/my-custom-plugin
# Build the plugin
yarn build
# This creates a ZIP file in:
# build/my-custom-plugin-1.0.0.zip
Advanced Features
Working with OpenSearch Data
Query OpenSearch from Backend
// In server/plugin.ts
router.get(
{
path: '/api/my-custom-plugin/search-data',
validate: {
query: schema.object({
index: schema.string(),
query: schema.string(),
}),
},
},
async (context, request, response) => {
const { index, query } = request.query;
try {
// Get OpenSearch client
const client = context.core.opensearch.client.asCurrentUser;
// Perform search
const searchResponse = await client.search({
index: index,
body: {
query: {
match: {
_all: query,
},
},
},
});
return response.ok({
body: {
hits: searchResponse.body.hits.hits,
total: searchResponse.body.hits.total,
},
});
} catch (error) {
this.logger.error(`Search failed: ${error}`);
return response.customError({
statusCode: 500,
body: { message: 'Search failed' },
});
}
}
);
Adding Plugin Configuration
Define Configuration Schema (server/index.ts)
import { schema, TypeOf } from '@osd/config-schema';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
apiKey: schema.string({ defaultValue: '' }),
maxResults: schema.number({ defaultValue: 100, min: 1, max: 1000 }),
});
export type MyPluginConfig = TypeOf<typeof configSchema>;
export const config = {
schema: configSchema,
};
Use Configuration in Plugin
// In server/plugin.ts
export class MyCustomPluginServer implements Plugin {
private config: MyPluginConfig;
constructor(initializerContext: PluginInitializerContext) {
this.logger = initializerContext.logger.get();
this.config = initializerContext.config.get<MyPluginConfig>();
}
public setup(core: CoreSetup) {
if (!this.config.enabled) {
this.logger.info('Plugin is disabled');
return {};
}
// Use config values
const maxResults = this.config.maxResults;
// ...
}
}
User Configuration File
Users can configure your plugin in config/opensearch_dashboards.yml:
myCustomPlugin:
enabled: true
apiKey: "your-api-key-here"
maxResults: 50
Creating Custom Visualizations
// In public/plugin.ts
public setup(core: CoreSetup, { visualizations }: SetupDeps) {
// Register custom visualization
visualizations.createReactVisualization({
name: 'my_custom_viz',
title: 'My Custom Visualization',
icon: 'visArea',
description: 'A custom visualization for specialized data',
visConfig: {
component: MyCustomVizComponent,
},
editorConfig: {
optionsTemplate: MyCustomVizOptions,
},
requestHandler: 'custom',
responseHandler: 'none',
});
}
Saved Objects
Define Saved Object Type
// In server/plugin.ts
public setup(core: CoreSetup) {
core.savedObjects.registerType({
name: 'my-custom-object',
hidden: false,
namespaceType: 'single',
mappings: {
properties: {
title: { type: 'text' },
description: { type: 'text' },
config: { type: 'object', enabled: false },
},
},
migrations: {},
});
}
Use Saved Objects
// Create
const savedObject = await context.core.savedObjects.client.create(
'my-custom-object',
{
title: 'My Object',
description: 'Description here',
config: { setting1: 'value1' },
}
);
// Read
const object = await context.core.savedObjects.client.get(
'my-custom-object',
'object-id'
);
// Update
await context.core.savedObjects.client.update(
'my-custom-object',
'object-id',
{ title: 'Updated Title' }
);
// Delete
await context.core.savedObjects.client.delete(
'my-custom-object',
'object-id'
);
Testing and Debugging
Unit Testing
Install Testing Dependencies
yarn add --dev @testing-library/react @testing-library/jest-dom
Example Component Test
// public/components/__tests__/app.test.tsx
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { MyPluginApp } from '../app';
describe('MyPluginApp', () => {
const mockCoreStart = {
notifications: {
toasts: {
addSuccess: jest.fn(),
},
},
};
it('renders the title', () => {
render(<MyPluginApp coreStart={mockCoreStart as any} />);
expect(screen.getByText('My Custom Plugin')).toBeInTheDocument();
});
it('increments counter on button click', () => {
render(<MyPluginApp coreStart={mockCoreStart as any} />);
const button = screen.getByText('Increment Counter');
fireEvent.click(button);
expect(screen.getByText('Counter: 1')).toBeInTheDocument();
});
});
Run Tests
yarn test
Debugging Tips
Enable Debug Logging
// In your plugin
this.logger.debug('Debug message here');
this.logger.info('Info message');
this.logger.warn('Warning message');
this.logger.error('Error message');
Browser DevTools
- Open browser DevTools (F12)
- Go to Sources tab
- Find your plugin files under
localhost:5601 - Set breakpoints
- Interact with your plugin to trigger breakpoints
Server-Side Debugging
Add this to your launch configuration:
{
"type": "node",
"request": "launch",
"name": "Debug OpenSearch Dashboards",
"program": "${workspaceFolder}/scripts/opensearch_dashboards",
"args": ["--dev", "--no-base-path"],
"console": "integratedTerminal"
}
Deployment
Installing Your Plugin
Method 1: Install from ZIP
# Build your plugin first
cd plugins/my-custom-plugin
yarn build
# Install the plugin
bin/opensearch-dashboards-plugin install file:///path/to/my-custom-plugin-1.0.0.zip
# Restart OpenSearch Dashboards
Method 2: Install from URL
bin/opensearch-dashboards-plugin install https://example.com/my-custom-plugin-1.0.0.zip
Method 3: Manual Installation
# Copy plugin to plugins directory
cp -r my-custom-plugin /path/to/opensearch-dashboards/plugins/
# Restart OpenSearch Dashboards
Removing Your Plugin
bin/opensearch-dashboards-plugin remove my-custom-plugin
# Restart OpenSearch Dashboards
Updating Your Plugin
# Remove old version
bin/opensearch-dashboards-plugin remove my-custom-plugin
# Install new version
bin/opensearch-dashboards-plugin install file:///path/to/my-custom-plugin-2.0.0.zip
# Restart OpenSearch Dashboards
Troubleshooting
Common Issues and Solutions
Issue: Plugin Won't Load
Symptoms:
- Plugin doesn't appear in sidebar
- Error messages in console
Solutions:
# 1. Check plugin ID matches in all files
# 2. Verify opensearch_dashboards.json is valid
# 3. Check server logs:
tail -f /var/log/opensearch-dashboards/opensearch-dashboards.log
# 4. Restart with verbose logging:
bin/opensearch-dashboards --verbose
Issue: Build Fails
Symptoms:
-
yarn buildproduces errors
Solutions:
# 1. Clear cache and rebuild
rm -rf build/ target/ node_modules/
yarn install
yarn build
# 2. Check TypeScript errors:
yarn type-check
# 3. Verify all imports are correct
Issue: API Calls Fail
Symptoms:
- 404 errors on API endpoints
- CORS errors
Solutions:
// 1. Verify route registration:
router.get(
{
path: '/api/my-custom-plugin/endpoint', // Must start with /api/
validate: false,
},
handler
);
// 2. Check server logs for errors
// 3. Test endpoint directly:
curl http://localhost:5601/api/my-custom-plugin/endpoint
Issue: Hot Reload Not Working
Solutions:
# 1. Stop the dev server
# 2. Clear build artifacts:
rm -rf optimize/ .cache/
# 3. Restart dev server:
yarn start
Performance Optimization
Lazy Loading
// Instead of:
import { HeavyComponent } from './heavy_component';
// Use:
const HeavyComponent = React.lazy(() => import('./heavy_component'));
// In your render:
<React.Suspense fallback={<div>Loading...</div>}>
<HeavyComponent />
</React.Suspense>
Minimize Bundle Size
// Avoid importing entire libraries:
// ❌ Bad:
import _ from 'lodash';
// ✅ Good:
import debounce from 'lodash/debounce';
Best Practices Checklist
Development
- [ ] Use TypeScript for type safety
- [ ] Follow Elastic UI Framework guidelines
- [ ] Implement proper error handling
- [ ] Add loading states for async operations
- [ ] Validate all user inputs
- [ ] Use meaningful variable and function names
- [ ] Add comments for complex logic
Security
- [ ] Validate all API inputs with schemas
- [ ] Sanitize user-provided data
- [ ] Use proper authentication/authorization
- [ ] Don't expose sensitive data in logs
- [ ] Implement rate limiting for APIs
Performance
- [ ] Lazy load heavy components
- [ ] Minimize bundle size
- [ ] Debounce frequent operations
- [ ] Use pagination for large datasets
- [ ] Cache frequently accessed data
Testing
- [ ] Write unit tests for components
- [ ] Write integration tests for APIs
- [ ] Test error scenarios
- [ ] Test with different data sets
- [ ] Perform cross-browser testing
Documentation
- [ ] Document all public APIs
- [ ] Provide usage examples
- [ ] Document configuration options
- [ ] Include troubleshooting guide
- [ ] Keep README up to date
Resources
Official Documentation
- OpenSearch Dashboards Docs: https://opensearch.org/docs/latest/dashboards/
- Plugin Development: https://opensearch.org/docs/latest/dashboards/dev-guide/
- API Reference: https://opensearch.org/docs/latest/api-reference/
GitHub Repositories
- OpenSearch Dashboards: https://github.com/opensearch-project/OpenSearch-Dashboards
- Example Plugins: https://github.com/opensearch-project/OpenSearch-Dashboards/tree/main/src/plugins
- Plugin Template: https://github.com/opensearch-project/opensearch-dashboards-plugin-template
UI Framework
- Elastic UI Framework: https://elastic.github.io/eui/
- EUI Components: https://elastic.github.io/eui/#/navigation/
- Design Guidelines: https://elastic.github.io/eui/#/guidelines/
Community
- OpenSearch Forum: https://forum.opensearch.org/
- Slack Channel: https://opensearch.org/slack
-
Stack Overflow: Tag
opensearch-dashboards
Learning Resources
- React Documentation: https://react.dev/
- TypeScript Handbook: https://www.typescriptlang.org/docs/
- REST API Best Practices: https://restfulapi.net/
Quick Reference
Common Commands
# Generate plugin
node scripts/generate_plugin.js <plugin-name>
# Install dependencies
yarn osd bootstrap
# Start dev server
yarn start
# Build plugin
yarn build
# Run tests
yarn test
# Install plugin
bin/opensearch-dashboards-plugin install <plugin-path>
# Remove plugin
bin/opensearch-dashboards-plugin remove <plugin-name>
# List installed plugins
bin/opensearch-dashboards-plugin list
Useful Code Snippets
Show Toast Notification
coreStart.notifications.toasts.addSuccess('Success message');
coreStart.notifications.toasts.addWarning('Warning message');
coreStart.notifications.toasts.addDanger('Error message');
Navigate to Another App
coreStart.application.navigateToApp('discover', {
path: '#/view/some-id',
});
Make HTTP Request
const response = await coreStart.http.get('/api/endpoint');
const data = await coreStart.http.post('/api/endpoint', {
body: JSON.stringify({ key: 'value' }),
});
Top comments (0)