Skip to main content
Building your own FrogBot Plugin is straightforward if you’re already familiar with FrogBot configuration. Plugins are functions that receive the incoming config and return the config your app should use. By abstracting your code into a plugin, you’ll be able to reuse your feature across multiple projects and make it available for other developers to use.

Plugins Recap

Here is a brief recap of how to integrate plugins with FrogBot, to learn more head back to the plugin overview page.

How to install a plugin

To install any plugin, simply add it to your FrogBot Config in the plugins array.

Initialization

The initialization process goes in the following order:
  1. Incoming config is validated
  2. Plugins execute, by order (see Order, slug, and options)
  3. Default options are integrated
  4. Sanitization cleans and validates data
  5. Final config gets initialized

Set up a development app

Create a regular FrogBot app to exercise your plugin during development:
Install your plugin package in that app, then add it to src/frogbot.config.ts:
Start the app with your package manager’s dev command and open http://localhost:3000.

Testing

A good test suite verifies the behavior your plugin adds and confirms that existing configuration is preserved. Use the test framework supported by your package, run the plugin inside a test FrogBot app, and cover both enabled and disabled options when your plugin provides them.

Building a Plugin

Now that we have our environment setup and dev project ready to go - it’s time to build the plugin!
To reiterate, the essence of a FrogBot Plugin is simply to extend the FrogBot Config - and that is exactly what we are doing in this file.

Spread syntax

Spread syntax (or the spread operator) is a feature in JavaScript that uses the dot notation (…) to spread elements from arrays, strings, or objects into various contexts. We are going to use spread syntax to allow us to add data to existing arrays without losing the existing data. It is crucial to spread the existing data correctly, else this can cause adverse behavior and conflicts with FrogBot Config and other plugins. Let’s say you want to build a plugin that adds a new collection:
First, you need to spread the config.collections to ensure that we don’t lose the existing collections. Then you can add any additional collections, just as you would in a regular FrogBot Config. This same logic is applied to other array and object-like properties such as admin and hooks:

Extending functions

Function properties cannot use spread syntax. The way to extend them is to execute the existing function if it exists and then run your additional functionality. Here is an example extending the onInit property:

Order, slug, and options

definePlugin builds a plugin factory with a slug, an optional order, and typed options. Its callback receives the incoming config, the options the factory was called with, and plugins, the app’s other plugins keyed by slug:
FrogBot runs plugins by order, lowest first. The default is 0, and plugins with the same order keep their plugins array order. Use 10 when your plugin needs collections or fields another plugin adds, like the API keys collection above, so it runs after that plugin wherever the app lists it. When a plugin with a slug throws, the error names it: [frogbot] plugin "plugin-key-notes" failed: …. Each plugin’s options are the object its factory was called with. To give other plugins typed access to them, register your slug by augmenting RegisteredPlugins:
If other plugins need your defaults, fill them in before calling the factory definePlugin returns, and pass the resolved object as options. The API keys plugin does this, so its collectionSlug option is always set.

Types

If your plugin has options, you should define and provide types for these options in a separate file which gets exported from the main index.ts.
If possible, include JSDoc comments to describe the options and their types. This allows a developer to see details about the options in their editor.

Best practices

In addition to the setup covered above, here are other best practices to follow:

Providing an enable / disable option

For a better user experience, provide a way to disable the plugin without uninstalling it.

Include tests in your GitHub CI workflow

If you’ve configured tests for your package, integrate them into your workflow to run the tests each time you commit to the plugin repository. Learn more about how to configure tests into your GitHub CI workflow.

Publish your finished plugin to npm

The best way to share and allow others to use your plugin once it is complete is to publish an npm package. This process is straightforward and well documented, find out more about creating and publishing a npm package here.

Add frogbot-plugin topic tag

Apply the tag frogbot-plugin to your GitHub repository. This will boost the visibility of your plugin and ensure it gets listed with existing FrogBot plugins.

Use Semantic Versioning (SemVer)

With the Semantic Versioning (SemVer) system you release version numbers that reflect the nature of changes (major, minor, patch). Ensure all major versions reference their FrogBot compatibility.