Map content to new structure
Define how to map your exported content to your new content model. To make the mapping easier, use the Kontent.ai Migration toolkit to ensure your content items and assets are correctly structured and referenced in your new project.
Mapping on paper
Before you start writing the mapping logic in code, we recommend you first define the mapping visually. You can do this on digital or analog paper. Visual mapping lets you and other stakeholders see how your existing content fits within the new content model. You’ll see which parts fit and which don’t. If a part doesn’t fit, you can adjust the content model or discard that part if it’s not needed. This lets you find possible gaps in your content model early on.Example mapping
Check the following diagram to see how an existing structure used for blog posts in one system can be mapped to a content model in Kontent.ai. The Kontent.ai content model in the example is based on the Article content modeling accelerator. Notice that the Blog post’s fields don’t always map one-to-one to the Article’s elements; sometimes, you need to transform the existing content to another format. Text fields can usually be mapped 1:1. For anything more complex, there is often a transformation involved.Mapping on paper can reveal gaps in your model. In this case, the Article’s Subtitle and Tags elements don’t match any of the original Blog post’s fields. In your case, it might be the other way around—some of the original fields might not match elements in the new model. For example, you might have fields that define visual information that you no longer need.If this happens, you might want to remove these extra elements unless you plan to use them for mapping from other types of content as well.
Mapping in code
Once you’ve verified everything on paper, you can move to the real thing. To simplify the mapping in code, use the Kontent.ai Migration toolkitInstall the Migration toolkit
To get started, create a Node.js app and install the Migration toolkit by running the following command in the terminal.# Add the Migration toolkit to your app
npm i @kontent-ai/migration-toolkit --save-dev
Migration toolkit 101
To migrate your exported content to a Kontent.ai project with the Migration toolkit, you need to:- Map your textual and structured content to the
MigrationItem
objects. - Map your binary files to the
MigrationAsset
objects. - Import the mapped content from the
MigrationItem
andMigrationAsset
objects to your Kontent.ai project.
import {
MigrationAsset,
MigrationItem,
importAsync,
} from "@kontent-ai/migration-toolkit";
// 1. Map the exported content to MigrationItems
const migrationItems: MigrationItem[] = [];
// 2. Map exported files to MigrationAssets
const migrationAssets: MigrationAsset[] = [];
// 3. Import the mapped data into a Kontent.ai project
await importAsync({
data: {
assets: migrationAssets,
items: migrationItems,
},
environmentId: "KONTENT_AI_ENVIRONMENT_ID",
apiKey: "MANAGEMENT_API_KEY",
});
Map exported content to content items
Kontent.ai stores content in content items. Depending on the number of languages in your project, each content item has one or more content item variants. The Migration toolkit’sMigrationItem
represents a single localized variant of a content item. This includes the variant’s metadata and elements. The specific elements depend on the content item’s content type. With each MigrationItem
, you can choose to specify content for the content item variant’s latest version, published version, or both.
import { MigrationItem } from "@kontent-ai/migration-toolkit";
// MigrationItem defines a localized variant of a content item
const migrationItem: MigrationItem = {
// Variant's metadata
system: {
// Name the content item. Item name is shared for all variants.
name: "My content item",
// Generate a unique content item codename
codename: "my_content_item",
// Assign the item to a collection
collection: { codename: "default" },
// Specify the variant's language
language: { codename: "en_us" },
// Specify the content type
type: { codename: "article" },
// Assign the item to a workflow
workflow: { codename: "default" },
},
versions: [
{
// Put the variant in a specific workflow step
workflow_step: { codename: "draft" },
elements: {
// Variant's content
// For each element specified by the item's content type, add properties named using element codenames.
// Example: element_codename: elementsBuilder.textElement({ value: 'plaintext' }),
},
},
],
};
MigrationItem
. We recommend using strongly typed models for the MigrationItem
objects.
import {
MigrationElementModels,
MigrationItem,
MigrationItemSystem,
elementsBuilder,
} from "@kontent-ai/migration-toolkit";
// We recommend you define the structure of your Kontent.ai content type
type LanguageCodenames = "default" | "en";
type CollectionCodenames = "default" | "global";
type WorkflowCodenames = "default" | "custom";
type WorkflowStepCodenames = "published" | "archived" | "draft";
type ContentTypeCodenames = "movie" | "actor";
type System<Codename extends ContentTypeCodenames> = MigrationItemSystem<
Codename,
LanguageCodenames,
CollectionCodenames,
WorkflowCodenames
>;
type MovieItem = MigrationItem<
// Defines the elements in the 'Movie' content type defined in Kontent.ai
{
title: MigrationElementModels.TextElement;
plot: MigrationElementModels.RichTextElement;
length: MigrationElementModels.NumberElement;
category: MigrationElementModels.MultipleChoiceElement;
poster: MigrationElementModels.AssetElement;
stars: MigrationElementModels.LinkedItemsElement;
seoname: MigrationElementModels.UrlSlugElement;
released: MigrationElementModels.DateTimeElement;
releasecategory: MigrationElementModels.TaxonomyElement;
},
System<"movie">,
WorkflowStepCodenames
>;
const movie: MovieItem = {
system: {
name: "Warrior",
// Ensure a unique codename. Check https://kontent.ai/learn/rules-for-codenames
codename: "warrior",
collection: { codename: "default" },
language: { codename: "default" },
type: { codename: "movie" },
workflow: { codename: "default" },
},
// Specify up to 2 versions of the variant - latest and published.
// The latest version can be in any workflow step.
versions: [
{
workflow_step: {
// You can publish the variant during the import, or use any other workflow step
codename: "published",
},
elements: {
title: elementsBuilder.textElement({ value: "Warrior" }),
length: elementsBuilder.numberElement({ value: 140 }),
category: elementsBuilder.multipleChoiceElement({
value: [
{
codename: "drama",
},
{
codename: "action",
},
],
}),
poster: elementsBuilder.assetElement({
value: [
{
codename: "warrior_teaser",
},
],
}),
plot: elementsBuilder.richTextElement({
// Check allowed HTML elements in rich text value at https://kontent.ai/learn/rich-text-in-mapi
value: `<h1>Warrior</h1><p>...</p>`,
components: [],
}),
releasecategory: elementsBuilder.taxonomyElement({
value: [
{
codename: "global_release",
},
],
}),
released: elementsBuilder.dateTimeElement({
value: "2011-09-09T00:00:00Z",
}),
seoname: elementsBuilder.urlSlugElement({
// The value is empty because it's autogenerated based on a dependent text element
mode: "autogenerated",
value: "",
}),
stars: elementsBuilder.linkedItemsElement({
value: [
{
codename: "tom_hardy",
},
],
}),
},
},
],
};
const migrationItems: MigrationItem[] = [movie];
Parse rich text content
Plan for any necessary parsing of your existing rich text content to map it to the HTML5 rich text format supported by Kontent.ai’s Management API. Remember that the rich text editor in Kontent.ai doesn’t support custom visual formatting, such as setting text color or font size, for a reasonMap binary files to assets
The Migration toolkit’sMigrationAsset
represents a single asset. You can reference assets by codenames in multiple MigrationItem
objects. Every asset can specify localized asset descriptions for use as alt text.
import { MigrationAsset } from "@kontent-ai/migration-toolkit";
import { readFileSync } from "fs"; // Only if using local data
const coverAsset: MigrationAsset = {
// You can read the data from anywhere, not just from the filesystem
binary_data: readFileSync("./movies/posters/warrior.jpg"),
// Ensure a unique asset codename. Check https://kontent.ai/learn/rules-for-codenames
// This codename is used to reference the asset in the MigrationItem object
codename: "warrior_teaser",
// Name the binary file linked to the asset
filename: "warrior_teaser.jpg",
// Name the asset
title: "Warrior cover",
// (Optional) Asign the asset to a collection
collection: {
codename: "default",
},
// (Optional) Specify localized asset descriptions
descriptions: [
{
language: {
codename: "default",
},
description: "Poster for Warrior movie",
},
],
};
const migrationAssets: MigrationAsset[] = [coverAsset];
Putting it together
Now that you know how to map your content and binary files to the migration objects, create mapping logic for your existing types of content.Once you have all the content mapped, you can start importing it to your project.