Basics
Features
Best Practices
Addon Development
Related Docs
Dark Mode

#Components

Your Addon can provide Components to the site. The user can disable these Components if they choose which prevents their Build Script from running and allows them to make their own Components with the same name.

#Component Schema

{

  // uneditable properties
  _id: '63a0db9dd37c3735b468e1f8',
  parentVersionId: '63a0458bee56d369bd5c79a6',
  managedByAddonId: '639b8f837f5fb8a39404280a',
  updatedAt: 1671486365027,
  createdAt: 1671486531695,

  // basic properties
  name: '',
  description: '',
  type: 'static',
  richTextType: '',
  isEnabled: true,

  // body properties
  lang: 'pug',
  body: '',

  // style properties
  styleLang: 'stylus',
  style: '',

  // fields
  fields: [],
  fieldGroups: [],
  displayField: '',

  // tags
  tags: [],

  // scripts
  script: '',
  dataScript: '',
  buildScript: '',

  // seo
  seoLang: '',
  seoBody: '',

  // help
  help: [],

}

#Uneditable Properties

NameDescription
_idAssigned by MercuryCMS when the Component is created
parentVersionIdUsed by MercuryCMS to manage revision history
managedByAddonIdAll of your created Components have this automatically added so they can be removed when the Addon is uninstalled
createdAtJavaScript Date the Component was created
updatedAtJavaScript Date the Component was last modified

#Basic Properties

NameDescription
nameThe Component's name that determines the HTML tag used to insert it. Use something that won't conflict with Components the user has created
descriptionOptional, but you should always provide a description of what the Component does
typeEither "static" or "vue". Default is "static"
richTextTypeOne of "", "block", "blockAndInline", or "inline". When set, defines how the user can use the Component in Rich Text Fields. Default is ""
isEnabledSet this to false to disable the Component, but the user can override this value

#Body Properties

NameDescription
langLanguage to use for the body. Either "html" or "pug". Default is "pug"
bodyBody HTML/Pug. Do not use minification for this. The user should be able to read it to understand what it does so they can easily provide their own CSS, wrapper Components, and understand how the Component's Slots work

#Style Properties

NameDescription
styleLangLanguage to use for the style. Either "css" or "stylus". Default is "stylus"
styleStyle CSS/Stylus. Do not use minification for this. The user should be able to read it to understand how variables are used, write their own CSS, etc.

#Fields

Under the hood, Component Attributes are called Fields. This is an array of objects with the following properties:

NameDescription
nameThe name of the Field. For example, a Field called "Per Page" would be entered as per-page="10" by the user when Templating
typeOne of "string" (Text), "multiline" (Text Area), "html", "color", "number", "boolean", "asset", "media", "enum" (Enumerable), "array", or "object". Default is "string"
defaultThe default value to use if the Attribute isn't specified
enumValuesA comma-separated list of values the Attribute the enum Field can accept. Only affects enum Fields. Example: "apple, banana, pear"
descriptionA description of what the Attribute does, used in the the interface

You can group these fields using objects within fieldGroups with the following schema:

NameDescription
nameOptional group name. This is used as a heading above the group of Fields.
descriptionOptional group description. This is used as text above the group of Fields.
fieldsAn array of camelCase Field names in the order they should appear in the group. For example, if you have fields called "Main Color", "Secondary Color", and "Error Color", you would use ['mainColor', 'secondaryColor', 'errorColor']

You can also set displayField on the Component to the name of the Attribute you want to be shown in Rich Text Fields. For example, if the Attribute name was "Cover Media ID", you could set displayField: "coverMediaId" to use the value of that Attribute for the preview image when the Component is being used in a Rich Text Field.

#Tags

This is a list of Tags to add to any page the Component is on in the order they should be added. See Tags for more information.

NameDescription
nameThe name of the Tag. For example: "Google Analytics"
locationOne of "head", "bodyStart", or "bodyEnd". Default is "head"
langThe language of the tag body. Either "pug" or "html". Default is "html"
bodyThe HTML/Pug body of the Tag

#Scripts

NameDescription
scriptThe script to be put on the any Page this Component is used on
dataScriptThe script used to create data used within the Component's Template
buildScriptThe script run for the Component at Build to generate Assets etc.

#SEO Properties

NameDescription
seoLangLanguage to use for the SEO body. Either "html" or "pug". Only applies to Vue Components. Default is "pug"
seoBodySEO body HTML/Pug. Do not use minification for this. Only applies to Vue Components

#Help

Help is an array of objects representing each of the Component's Help Pages with the following properties:

NameDescription
nameThe Help Page's name
pathThe Help Page's path. For example: "/"
bodyMarkdown for the Help Page's body

#Authoring Addon Components

Trying to write body, style, script, dataScript, and buildScript within your code is very difficult. It is recommended you first write and test the Component in MercuryCMS, then export it as a zip. You can then include the exported component.zip file in your Addon Package.

#Creating Components

You can create Components by using cms.upsertComponent(). This function will look to see if a specific Component exists and update it, or create it if it doesn't exist.

let componentDef = {
  name: 'My Component',
  description: 'A Demo Component',
  type: 'static',
  body: '.my-component This is a demo!',
  style: '.my-component\n  color {{ attr.color }}',
  fields: [
    {name: 'Color', type: 'color', default: '#ff0000', description: 'Text color'},
  ],
}

// use static-cms-addon
import cms from 'static-cms-addon'

let component = await cms.upsertComponent({name: 'My Component'}, componentDef, 'Added Color Attribute.')
console.log(component._id) // "63a0db9dd37c3735b468e1f8"

// use axios
let response = await axios.post(`http://localhost:${cmsPort}/api/addon/${addonId}/component`, {match: {name: 'My Component'}, component: componentDef, publishComment: 'Added Color Attribute.'})
console.log(response.data.component._id) // "63a0db9dd37c3735b468e1f8"

The first argument to upsertComponent() is the fields to match against. This should typically just be name. The second argument is the Component definition, and the third argument is an optional Publish Comment. You can use this to provide information about what changed in the Component. This will not be used if the Component is new, and will only be shown if the Component you are upserting has actually changed.

You can also load the Component from a zip or folder using cms.loadComponentPackage().

let componentDef = cms.loadComponentPackage('components/myComponent.component.zip').component
let component = await cms.upsertComponent({match: componentDef.name}, componentDef)

#Listing Components

You can use cms.getComponents() to get a list of the Components your Addon has created.

// use static-cms-addon
import cms from 'static-cms-addon'

let components = await cms.getComponents()
console.log(components.map(component => component.name)) // ['My Component', 'Another Component']

// use axios
let response = await axios.get(`http://localhost:${cmsPort}/api/addon/${addonId}/component`)
console.log(response.data.components.map(component => component.name)) // ['My Component', 'Another Component']

#Deleting Components

You can use cms.deleteComponents() to delete Components your Addon has created.

// use static-cms-addon
import cms from 'static-cms-addon'

let components = await cms.getComponents()
let component = components.find(component => component.name == 'My Component')
await cms.deleteComponents([component._id])

// use axios
let response = await axios.get(`http://localhost:${cmsPort}/api/addon/${addonId}/component`)
let component = response.data.components.find(component => component.name == 'My Component')
await axios.post(`http://localhost:${cmsPort}/api/addon/${addonId}/component/delete`, {componentIds: [component._id]})

#User Modification

Users cannot modify your Components, but they are expected to use them in a number of ways:

  • Users can use your Component within their own Pages, Layouts, Components, and RichText Fields in Collections.
  • Users can provide your Component Attributes whenever they use it, including creating a wrapper Component to set Attributes. MercuryCMS also allows the user to override any of your Component's default Attribute values. These settings are stored outside of the Component itself, so you can safely delete the Component and replace it with an updated version and the user's Attribute overrides will be retained.
  • Users can put HTML content into your Slots. You should provide as many Slots as you can so users can easily add content their site needs without having to disable your Component and write their own custom version that won't be updated when the Addon is updated.
  • Users can write their own CSS to override your Component's CSS, but you should make these options available as Attributes so you can easily change your Component's CSS without breaking the user's site.
  • It is recommended you set variables as default values. For example, you can use {{ addon.myaddon.settings.postsPerPage }} as the default value for the per-page Attribute. The user can now change this through your Addon's settings Screen, or can use their own value from their own Collections, Build Script, etc.