Beacon is a command-line tool for serializing and deserializing data from a stack in the Contentstack headless CMS platform.
Beacon enables full-stack synchronization by allowing users to:
-
Serialize (export) a stack's entire contents, including entries, assets, content types, global fields, and taxonomies, into the file system.
-
Store the serialized data under version control for tracking and CI/CD deployment.
-
Deserialize (import) the stored data into a target stack, restoring its state.
-
Create and maintain local backups of stack contents.
-
Clear a stack by removing all its contents.
Beacon is particularly useful for teams working with multiple Contentstack environments, ensuring content model consistency across development, staging, and production.
Beacon is available as an NPM package under @arke-systems/beacon-cli. It can
be installed using any package manager that supports NPM packages.
yarn add --dev @arke-systems/beacon-clinpm install --save-dev @arke-systems/beacon-cliBeacon provides a CLI executable named beacon. To invoke it, use your
package manager:
yarn beacon <command>
# or
npx beacon <command>Completely empties a stack by removing all entries, content types, global fields, taxonomies, and assets.
Serializes a stack's content into the file system for version control or backup.
Deserializes the contents from the file system into the stack.
| Option | Description | Required? |
|---|---|---|
--api-key <value> |
API key for the stack. | ✅ |
--api-timeout <value> |
Timeout for API requests in milliseconds. | ❌ |
--base-url <value> |
URL for the Contentstack Management API. | ✅ |
--branch <value> |
Stack branch to operate on. Defaults to main. |
✅ |
--config-file <value> |
Path to the YAML configuration file. | ❌ |
--management-token <value> |
Token for authentication with the stack. | ✅ |
--environment <value> |
Named configuration environment. | ❌ |
--verbose |
Enables verbose logging. | ❌ |
--help |
Displays help information. | ❌ |
| Option | Description | Default |
|---|---|---|
--schema-path <path> |
Path to store serialized data. | ./cs/schema |
--extension [name:uid] |
Maps third-party plugin UIDs to stable names for portability. | N/A |
--json-rte-plugin [name:uid] |
Similar to --extension but for JSON RTE plugins. |
N/A |
| Option | Description | Default |
|---|---|---|
--deletion-strategy <delete,ignore,warn> |
Controls deletion behavior. | warn |
Some third-party plugins in Contentstack provide custom field types or JSON RTE
plugins. Since plugin unique IDs (UIDs) are stack-specific, Beacon provides
--extension and --json-rte-plugin options to map these UIDs when
transferring data between stacks.
When a third-party plugin, such as Bynder, is installed in a stack, Contentstack assigns a unique ID to its custom field type and JSON RTE plugin. These UIDs are not exposed in the Contentstack UI, and they are different for every stack. If serialized data references these UIDs directly, it may break when restored to another stack where the UIDs are different. Beacon allows mapping these UIDs to stable names so that they can be translated correctly when deserializing data into a different stack.
To obtain the correct UID values for third-party plugins:
-
Create a Test Content Type:
-
In the Contentstack admin UI, create a new content type that includes the third-party plugin.
-
If the plugin provides a JSON RTE plugin, ensure it is explicitly selected as active for the field.
-
-
Export the Content Type:
- Use the Contentstack admin UI to export the content type as JSON. The exported JSON will contain minimized data, making it challenging to read.
-
Locate the UID Values:
-
Within the exported JSON, find the block of JSON that corresponds to the custom field. It will look something like this:
{ "data_type": "json", "display_name": "Background Image", "extension_uid": "blt6b7c082b-example", "field_metadata": { "extension": true }, "mandatory": false, "multiple": false, "non_localizable": false, "uid": "background_image", "unique": false } -
The
extension_uidvalue (blt6b7c082b-examplein this example) is the UID for the custom field.
-
-
Identify the JSON RTE Plugin UID:
-
Similarly, locate the JSON RTE plugin's UID within the exported JSON. It will be nested under the JSON RTE field’s configuration:
{ "data_type": "json", "display_name": "Content", "field_metadata": {}, "mandatory": false, "multiple": false, "non_localizable": false, "plugins": ["bltd0dac425-example"], "uid": "content", "unique": false }, -
The
pluginsarray contains the JSON RTE plugin UID (bltd0dac425-examplein this example).
-
-
Use the UID Values in Beacon:
-
Map these UIDs to stable names using
--extensionand--json-rte-pluginoptions:yarn beacon pull \ --extension bynder:blt6b7c082b-uid-in-source-stack \ --json-rte-plugin bynder:bltd0dac425-uid-in-source-stack
-
When pushing data to another stack, use the same mapping:
yarn beacon push \ --extension bynder:blt6b7c082b-uid-in-target-stack \ --json-rte-plugin bynder:bltd0dac425-uid-in-target-stack
-
Note: the word
bynderin the above examples is user-defined and arbitrary. It is used to identify the third-party plugin, and it will be serialized in the data instead of the stack-specific UID values. You can use any name that makes sense to you, except the same name must be used consistently across all commands. It is not a conflict to use the same name for both the--extensionand--json-rte-pluginoptions.
-
By following these steps, developers can ensure that serialized content remains portable between stacks, preventing UID mismatches that could otherwise break integrations.
In addition to the command line, Beacon allows specifying options via
environment variables or an optional YAML configuration file (beacon.yaml).
The order of precedence is:
- Command line
- Environment variables
- Configuration file
That is, options specified on the command line have the highest precedence, followed by environment variables, and finally the configuration file.
| Variable | Maps To | Required? | Default |
|---|---|---|---|
Contentstack_Api_Key |
--api-key |
✅ | N/A |
Contentstack_Management_API |
--base-url |
✅ | N/A |
Contentstack_Branch |
--branch |
❌ | main |
Contentstack_Management_Token |
--management-token |
✅ | N/A |
Beacon_Extension |
--extension |
❌ | N/A |
Beacon_Plugin |
--json-rte-plugin |
❌ | N/A |
The YAML configuration file allows for additional options.
Example:
# yaml-language-server: $schema=node_modules/@arke-systems/beacon-cli/dist/cfg/Config.schema.yaml
client:
api-key: bltcfcf264c-example
management-token: cs-example
branch: main
base-url: https://api.contentstack.io/
timeout: 10000
schema:
deletion-strategy: warn # delete | ignore | warn
schema-path: ./cs/schema
extension:
Bynder: blt6b7c082b-example
json-rte-plugin:
Bynder: bltdd6396f0-example
# Include or exclude assets using glob patterns.
assets:
include: ['**']
exclude: []
# Determine whether to serialize taxonomy terms or just the
# taxonomy structure.
taxonomies:
page_type: taxonomy and terms
'*': only taxonomy
environments:
dev:
client: { api-key: bltcfcf264c-dev-example }
schema:
deletion-strategy: delete
extension: { Bynder: blt6b7c082b-dev-example }
json-rte-plugin: { Bynder: bltdd6396f0-dev-example }
production:
client: { api-key: bltcfcf264c-prod-example }
schema:
deletion-strategy: ignore
extension: { Bynder: blt6b7c082b-prod-example }
json-rte-plugin: { Bynder: bltdd6396f0-prod-example }
verbose: falseThe configuration file may contain an optional environments section. This
section allows defining multiple named environments, each with its own
configuration. This is useful for managing different environments (e.g.,
development, staging, production) with different settings.
The environments section is a map of environment names to configuration
values. Each environment can override the base configuration values
defined in the client and schema sections.
When a named environment is specified using the --environment option,
the settings for that environment will be merged with the base
configuration. During this merge, the following rules apply:
-
schema.extension,schema.json-rte-plugin, andschema.taxonomiesare merged, with values from the named environment being used in addition to values from the base configuration. -
schema.assets.includeandschema.assets.excludeare concatenated, with values from the named environment being added to the base configuration. -
All other values will prefer the named environment.
Although the configuration file supports including the management token,
it is highly recommended to omit this value from the configuration file
for security reasons. Instead, use the --management-token command line
option or set the Contentstack_Management_Token environment variable.
yarn beacon pull \
--api-key bltcfcf264c-example \
--management-token cs-example \
--base-url https://api.contentstack.ioyarn beacon push \
--api-key bltcfcf264c-example \
--management-token cs-example \
--base-url https://api.contentstack.ioyarn beacon clear \
--api-key bltcfcf264c-example \
--management-token cs-example \
--base-url https://api.contentstack.ioThe recommended configuration for incorporating Beacon into a project is to
store any stack-specific settings in the project's .env file, outside of
source control. Any shared team settings can then be stored in the beacon.yaml
file, which should be committed to source control. This permits individual
developers to target their personal stack and also permits CI/CD tooling to
operate effectively on higher environments.
For example:
# .env (ignored by Git)
Contentstack_Api_Key=bltcfcf264c-example
Contentstack_Management_API=https://api.contentstack.io/
Contentstack_Management_Token=cs-example
Beacon_Extension=Bynder:blt6b7c082b-example
Beacon_Plugin=Bynder:bltdd6396f0-example# .env.example (committed to Git)
Contentstack_Api_Key=
Contentstack_Management_API=https://api.contentstack.io/
Contentstack_Management_Token=
Beacon_Extension=
Beacon_Plugin=# beacon.yaml
schema:
schema-path: ./cs/schema
assets:
include:
- Chrome/**
- Errors/404.jpg
- Logo/logo-412.webp
taxonomies:
page_type: 'taxonomy and terms'
'*': only taxonomy# .yarnrc.yml
injectEnvironmentFiles: [.env?]Under this configuration, the push, pull, and clear commands become:
yarn beacon pull
yarn beacon push
yarn beacon clearFor CI/CD environments, the .env file will not exist, so environment variables
should be set by the CI/CD tooling instead.
This project uses yarn as a package manager. Use yarn install to install
the dependencies.
To test locally, you will need an .env file. Copy the .env.example file to
create your own .env file.
Some development scripts are provided:
yarn build- Compile TypeScript code.yarn clean- Remove compiled code.yarn cli- Invoke the CLI.yarn lint- Invoke ESLint.yarn pretty- Invoke Prettier.yarn test- Invoke unit tests.yarn workspace @arke-systems/beacon-cli generate- Rebuild OpenAPI type definitions.
This repository provides a CLI tool that can be installed into other projects as an NPM package.
New releases of this tool are handled by the publish-package GitHub Action.
To invoke this action, create and publish a new release in GitHub.
Beacon is licensed under the MIT License.