Skip to main content
When customizing your Back-end behavior, it is quite common to have to perform the same tasks on multiple Fields and Collections. Plugins are the answer to that need, and you are strongly encouraged to use them everywhere you notice that your customization files could benefit from code factorization.

Using plugins

Plugins are used by either importing a module, or installing the relevant package, and then calling the use method. Depending on the plugin, options may be provided.
import { createAgent } from '@forestadmin/agent';
import { createFileField } from '@forestadmin/plugin-aws-s3';
import { removeTimestamps } from './plugins/remove-timestamps';

// The .use() method can be called both on the agent and on collections.
createAgent()
  // Some plugins do not require options
  .use(removeTimestamps)

  // Others do
  .customizeCollection('accounts', collection =>
    collection.use(createFileField, { fieldname: 'avatar' }),
  );

Writing plugins

A plugin is nothing more than an async function that performs customizations.
export async function removeTimestamps(dataSource, collection) {
  // Allow the plugin to be used both on the dataSource or on individual collections
  const collections = collection ? [collection] : dataSource.collections;

  // Remove fields
  for (const currentCollection of collections) {
    currentCollection.removeField('createdAt');
    currentCollection.removeField('updatedAt');
  }
}

Write your own plugin

Each plugin is nothing more than an async function that can perform customizations at either Back-end level, Collection level, or both.
export async function removeTimestamps(dataSource, collection, options) {
  // ... call customization methods here
}
3 parameters are provided:
NameDescription
dataSourceAn object that allows customizing the whole agent. It has the same interface as the Agent you manipulate outside of plugins
collectionAn object that allows customizing the collection that the plugin was called from (null if the plugin was called on the Back-end). It is the same object passed when you call customizeCollection
optionsOptions that are provided to the plugin. There is no set structure for this parameter, as each plugin will provide specific mandatory or optional options

Making your plugin act differently depending on the collection

When making a plugin, you may want it to generalize to many different Collections. This can be achieved by adopting different behavior depending on the schema of the Collection being targeted.
export async function removeTimestamps(dataSource, collection, options) {
  for (const currentCollection of dataSource.collections) {
    if (currentCollection.schema.fields.createdAt) {
      currentCollection.removeField('createdAt');
    }

    if (currentCollection.schema.fields.updatedAt) {
      currentCollection.removeField('updatedAt');
    }
  }
}