# Developing script plugins
Script plugins are plugins that provide code developed in JavaScript or TypeScript to extend GROWI's functionality. We recommend developing in TypeScript and transpiling with Vite.
For the basic flow of plugin development, please also refer to Plugin Development Basics.
# Basic structure of script plugins
A typical script plugin has the following structure:
growi-plugin-example/
├── client-entry.tsx # Plugin entry point
├── package.json # Plugin information and dependencies
├── src/ # Source code
│ ├── Component.tsx # React component
│ └── Component.css # Component styles
├── tsconfig.json # TypeScript configuration
└── vite.config.ts # Build configuration
# Examples of actual plugin structures
# Example 1: copy-code-to-clipboard plugin
growi-plugin-copy-code-to-clipboard (opens new window) is a simple plugin that adds a copy button to code blocks.
growi-plugin-copy-code-to-clipboard/
├── client-entry.ts # Plugin entry point
├── package.json # Plugin information and dependencies
├── src/ # Source code
│ ├── components/ # Components directory
│ │ └── CopyCodeButton.tsx # Copy button component
│ └── styles/ # Styles directory
│ └── CopyCodeButton.css # Button styles
├── tsconfig.json # TypeScript configuration
└── vite.config.ts # Build configuration
# Example 2: datatables plugin
growi-plugin-datatables (opens new window) adds DataTable functionality to GROWI tables.
growi-plugin-datatables/
├── client-entry.tsx # Plugin entry point (using JSX)
├── package.json # Plugin information and dependencies
├── src/ # Source code
│ ├── CalcMethod.ts # Calculation method related file
│ ├── DataTable.tsx # DataTable component
│ ├── DataTable.css # DataTable component styles
│ ├── DataTableCustom.d.ts # Type definition file
│ └── mock/ # Mock data directory
├── tsconfig.json # TypeScript configuration
└── vite.config.ts # Build configuration
# Development procedure
# 1. Edit package.json
{
"name": "growi-plugin-example", // Plugin name
"version": "1.0.0",
"description": "Example GROWI plugin", // Plugin description
"type": "module", // Set as ES module
"keywords": [
"growi",
"growi-plugin"
],
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
},
"devDependencies": {
"@growi/pluginkit": "^1.1.0", // GROWI plugin development kit
"typescript": "^x.x.x",
"vite": "^^x.x.x" // Build tool
},
"growiPlugin": {
"schemaVersion": "4",
"types": [ // Multiple plugin types can be set simultaneously
"script"
]
},
// Other settings...
}
# 2. Install libraries
$ pnpm install
# 3. Implement the plugin
To implement a script plugin, you need to implement the following three elements in the main entry point file (client-entry.tsx in this example):
- activate function: Function executed when the plugin is activated
- deactivate function: Function executed when the plugin is deactivated
- Plugin registration: Registration to the
window.pluginActivators
object- Register the activate and deactivate functions with the plugin name as the key
- This allows the GROWI core to find the plugin by searching this object at startup
//client-entry.tsx
const activate = (): void => {
// Check if GROWI core is available
if (growiFacade == null || growiFacade.markdownRenderer == null) {
return;
}
// Process to execute
};
const deactivate = (): void => {
// Cleanup process (implement as needed)
};
// Registration to the `window.pluginActivators` object
if ((window as any).pluginActivators == null) {
(window as any).pluginActivators = {};
}
(window as any).pluginActivators['growi-plugin-my-feature'] = {
activate,
deactivate,
};
# Implementing React components
In script plugins, you can customize GROWI's UI using React components. A practical implementation example can be found in growi-plugin-copy-code-to-clipboard (opens new window).
# 4. Vite configuration
Configure build settings in the vite.config.ts file.
// vite.config.ts
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [react()],
build: {
manifest: true,
rollupOptions: {
input: ['/client-entry.tsx'],
},
},
});
# 5. Build the plugin
$ pnpm build
This generates built files in the dist
directory.