The purpose of this tool is to facilitate content migration to & from Kontent.ai environments. It can be used to simplify migration from external systems and also provides a built-in migration between kontent.ai environments.
Tip
This library aims to streamline the migration to / from Kontent.ai environments by providing an abstraction layer which handles creation /
updates of content items, language variants, moving items through workflow, publishing, archiving, downloading binary data, uploading
assets, id
to codename
translation and more.
This library can only be used as a library both in node.js
or as a CLI
utility.
Use --help
anytime to get information about available commands and their options.
npx @kontent-ai/migration-toolkit@latest --help
# you can also install the package globally, or locally
npm i @kontent-ai/migration-toolkit -g
# with the package installed, you can call the tool as follows
kontent-ai-migration-toolkit --help
# or check details of particular command
kontent-ai-migration-toolkit migrate --help
Note
You can run kontent-ai-migration-toolkit
many times over without being worried that duplicate content items / assets are created.
You may migrate content (items & asset) between Kontent.ai environments. For migrating Data model / structure see Data Ops instead.
Caution
We recommend migrating to test / dev environments first to ensure nothing unexpected happens..
Config | Value |
---|---|
sourceEnvironmentId | Id of source environment (required) |
sourceApiKey | Management API key of source environment (required) |
targetEnvironmentId | Id of target environment (required) |
targetApiKey | Management API key of target environment (required) |
language | Codename of language that items will be exported in (required) |
items | Comma separated list of items that will be exported (required) |
force | Can be used to disable confirmation prompts. Available options: true & false . Defaults to false |
# Migrate from Kontent.ai environment into another Kontent.ai environment
kontent-ai-migration-toolkit migrate --targetEnvironmentId=x --targetApiKey=x --sourceEnvironmentId=x --sourceApiKey=x --language=default --items=itemA,itemB
Caution
We do not recommended importing into a production environment directly without testing. Instead you should first create a testing environment and run the script there to make sure everything works as you intended to.
Note
When importing it is essential that the target project structure (i.e. Content types
, Taxonomies
, Collections
, Workflows
,
languages
...) are consistent with the ones defined in source environment. Any inconsistency in data such as referencing inexistent
taxonomy term, incorrect element type and other inconsistencies may cause import to fail.
Config | Value |
---|---|
targetEnvironmentId | Id of Kontent.ai environment (required) |
targetApiKey | Management API key (required) |
filename | Name of the zip file (required) |
baseUrl | Custom base URL for Kontent.ai API calls |
force | Can be used to disable confirmation prompts. Options: true & false . Defaults to false |
createReportFile | When enabled, a detailed json file will be created in current dir with import details. Options: true & false . Defaults to false |
# Import into target environment
kontent-ai-migration-toolkit import --targetEnvironmentId=x --targetApiKey=x --filename=data.zip
This library can also be used to export content items & assets from Kontent.ai environments. However, when migration from 3rd party system
you typically only use the import
capabilities of this repository.
Config | Value |
---|---|
sourceEnvironmentId | Id of Kontent.ai environment (required) |
sourceApiKey | Management API key of Kontent.ai environment (required) |
language | Codename of language that items will be exported in (required) |
items | Comma separated list of items that will be exported (required) |
filename | Name of the zip file |
baseUrl | Custom base URL for Kontent.ai API calls |
# Export from Kontent.ai environment
kontent-ai-migration-toolkit export --sourceEnvironmentId=x --sourceApiKey=x --language=default --items=itemA,itemB
You can use this library when exporting from 3rd party systems (i.e. legacy CMS) as it will abstract your from using Kontent.ai Management API directly.
The main focus is therefore on transforming the data you need to migrate into a format this library supports. The main migration models are
MigrationItem
and MigrationAsset
. For creating element values elementsBuilder
.
See below example of using a strongly typed model and migrating a single item with an asset.
/**
* Optionally (but highly recommended) you may define a migration model
* representing the environment you are trying to migrate into.
*/
type LanguageCodenames = 'default' | 'en';
type CollectionCodenames = 'default' | 'global';
type WorkflowCodenames = 'default' | 'custom';
type ContentTypeCodenames = 'article' | 'author';
type WorkflowStepCodenames = 'published' | 'archived' | 'draft';
type ContentTypeCodename<Codename extends ContentTypeCodenames> = Codename;
type ArticleItem = MigrationItem<
{
title: MigrationElementModels.TextElement;
rating: MigrationElementModels.NumberElement;
related_pages: MigrationElementModels.LinkedItemsElement;
teaser_image: MigrationElementModels.AssetElement;
},
MigrationItemSystem<ContentTypeCodename<'article'>, LanguageCodenames, CollectionCodenames, WorkflowCodenames>,
WorkflowStepCodenames
>;
const migrationItem: ArticleItem = {
system: {
name: 'My article',
// codename is primary identifier - also used for validating whether asset exists in target env
codename: 'myArticle',
collection: {
// collection codename must match the collection in your target K.ai environment
codename: 'default'
},
language: {
// language codename must match the language in your target K.ai environment
codename: 'en'
},
type: {
// type codename must match the content type codename in your target K.ai environment
codename: 'article'
},
workflow: {
codename: 'default'
}
},
versions: [
{
workflow_step: {
codename: 'published'
},
elements: {
title: elementsBuilder.textElement({ value: 'Title of the article' }),
rating: elementsBuilder.numberElement({ value: 5 }),
related_pages: elementsBuilder.linkedItemsElement({
value: [
{
codename: 'pageA'
},
{
codename: 'pageB'
}
]
}),
// assets are referenced by their codename
teaser_image: elementsBuilder.assetElement({ value: [{ codename: 'article_teaser' }] })
}
}
]
};
const migrationAsset: MigrationAsset = {
// codename of the asset - Used for validating whether asset exists in target env
codename: 'article_teaser',
// filename will be used in K.ai asset as a filename
filename: 'article_teaser.jpg',
// title will be used in K.ai asset as a title
title: 'Article teaser',
// binary data of the asset you want to upload
binaryData: <BinaryData>,
// collection assignment
collection: {
codename: 'teasers'
},
// description of asset in project languages
descriptions: [
{
description: 'Teaser of the article',
language: {
codename: 'en_uk'
}
}
]
};
Once you are happy with the data, you can import them to Kontent.ai using the importAsync
function.
await importAsync({
environmentId: environmentId,
apiKey: apiKey,
data: {
assets: [migrationAsset],
items: [migrationItem]
}
});
The Migration Toolkit creates content items that are not present in target project. If the content item exists in target project (based on
item's codename
) the item will be updated, otherwise it will be created. No duplicate items will be created. The workflow of the item in
target environment will be set to match the source environment.
If asset exists in target project (based on asset's codename
), the asset upload will be skipped and not uploaded at all. Otherwise the
asset will be created in target environment.
If you have a reference to a content item or asset (i.e. in linked items element, asset element, rich text element...) the migration toolkit
first checks whether the referenced object exists (based on item or asset codename
) and if it does, successfuly sets the reference. If the
object does not exist, it will be referenced by an external_id
which creates a placeholder for the item until it becomes available.
See the table below to learn how external_id
is generated by default:
Object type | Template | Sample codename of the object |
Generated external_id |
---|---|---|---|
Asset | asset_{codename} |
my_file | asset_my_file |
Content item | item_{codename} |
article | item_article |
If you need to change the way external_id
is created, you may supply a custom implementation of externalIdGenerator
within import /
migrate functions.
- Custom asset elements are not supported (= values of these elements are not exported or imported )
The Node.js limits the maximum header size of HTTP requests. In some cases it may be required for you to increase this limitation to be able
to successfully fetch data from Kontent.ai. You can do so by using the max-http-header-size
option
(https://nodejs.org/api/cli.html#--max-http-header-sizesize)
Example script call:
node --max-http-header-size 150000 %USERPROFILE%\AppData\Roaming\npm\node_modules\kontent-ai-migration-toolkit\dist\cjs\lib\node\cli\app --action=export --apiKey=<key> --environmentId=<environmentId>