Import Content

Introduction

Goal

Migrate content stored in a different CMS to Bloomreach Content using the Content Batch Import API.

Background

When coming from a different CMS, a lot of content might need to be migrated into Bloomreach Content.

Our goal is to support this use case and make it as easy as possible for developers to quickly migrate into Bloomreach Content.

We solve the migration of data problem by offering a Content Batch Import API. It enables developers to import large amounts of content into a Bloomreach project.

In this tutorial, we'll walk you through the process step by step with examples showing how to import content into Bloomreach Content. You can import both documents and/or pages in the batch request.

Prerequisites

Before starting:

To make the API requests in this tutorial, we recommend using the Postman Collection to make the Content Batch Import API requests. However, you can use any other method or tool you like such as curl or httpies.

Step by Step Tutorial

1. Convert Your Content to Our Format

The batch import works by uploading a JSON lines file, also known as an NDJSON or new line delimited JSON file. Each line of the file contains a JSON object representing a single document or page, in the same format used by the Content Management API.

You can follow our detailed Recipe on what each field means in the batch import format:

In case you just want to see it working for yourself and quickly try out with some dummy content, consider the following example (here represented as a regular JSON array for readability) for a channel named "my-channel":

[
{
    "type": "document",
    "contentType": "brxsaas:banner",
    "fields": [
        {
            "name": "title",
            "value": [
                "Our team is ready for your next product"
            ]
        },
        {
            "name": "content",
            "value": [
                "<p>example content</p>"
            ]
        },
        {
            "name": "image",
            "value": [
                "/"
            ]
        },
        {
            "name": "cta",
            "value": [
                "Start your next project"
            ]
        },
        {
            "name": "link",
            "value": [
                "/content/documents/my-channel/pages/products/all"
            ]
        }
    ],
    "name": "next-project11",
    "displayName": "Next Project11",
    "path": "/content/documents/my-channel/banners/next-project11"
},
{
    "type": "document",
    "contentType": "brxsaas:banner",
    "fields": [
        {
            "name": "title",
            "value": [
                "Brand 1"
            ]
        },
        {
            "name": "content",
            "value": [
                "<p>Sample content</p>"
            ]
        },
        {
            "name": "image",
            "value": [
                "/content/gallery/my-channel/banners/brand-1.jpg"
            ]
        },
        {
            "name": "cta",
            "value": []
        },
        {
            "name": "link",
            "value": [
                "/content/documents/my-channel/pages/products/all"
            ]
        }
    ],
    "name": "brand-111",
    "displayName": "Brand 111",
    "path": "/content/documents/my-channel/banners/brand-111"
},
{
    "type": "page",
    "relativePath": "pages/home-222",
    "channelId": "my-channel",
    "name": "home-222",
    "displayName": "Home 222",
    "layout": "two-column",
    "document": {
        "contentType": "brxsaas:content",
        "fields": [
            {
                "name": "title",
                "value": [
                    "My page"
                ]
            },
            {
                "name": "introduction",
                "value": [
                    "Sample introduction"
                ]
            },
            {
                "name": "content",
                "value": [
                    "Example page content"
                ]
            },
            {
                "name": "image",
                "value": [
                    "/"
                ]
            },
            {
                "name": "date",
                "value": []
            }
        ]
    },
    "containers": [
        {
            "path": "top",
            "components": [
                {
                    "componentDefinition": "brx-reference-spa/referencespa-single-banner-carousel",
                    "componentConfigurations": [
                        {
                            "id": "DEFAULT",
                            "content": null,
                            "parameters": [
                                {
                                    "name": "alignment",
                                    "value": "center"
                                },
                                {
                                    "name": "document1",
                                    "value": "banners/safe-workspace-1"
                                },
                                {
                                    "name": "document2",
                                    "value": "banners/safe-workspace-2"
                                },
                                {
                                    "name": "interval",
                                    "value": "10000"
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        {
            "path": "main",
            "components": [
                {
                    "componentDefinition": "brx-reference-spa/referencespa-titleandtext",
                    "componentConfigurations": [
                        {
                            "id": "DEFAULT",
                            "content": {
                                "contentType": "titleandtext",
                                "fields": [
                                    {
                                        "name": "title",
                                        "value": [
                                            "Welcome to brX ContentX"
                                        ]
                                    },
                                    {
                                        "name": "text",
                                        "value": [
                                            "Welcome to the Bloomreach Sample Front-end Application for the brX Content."
                                        ]
                                    }
                                ]
                            },
                            "parameters": [
                                {
                                    "name": "titlesize",
                                    "value": "H3"
                                },
                                {
                                    "name": "textalignment",
                                    "value": "left"
                                },
                                {
                                    "name": "style",
                                    "value": "style1"
                                }
                            ]
                        }
                    ]
                },
                {
                    "componentDefinition": "brx-reference-spa/referencespa-titleandtext",
                    "componentConfigurations": [
                        {
                            "id": "DEFAULT",
                            "content": {
                                "contentType": "titleandtext",
                                "fields": [
                                    {
                                        "name": "title",
                                        "value": [
                                            ""
                                        ]
                                    },
                                    {
                                        "name": "text",
                                        "value": [
                                            "We have tried to keep it as clean, effective and simple as possible"
                                        ]
                                    }
                                ]
                            },
                            "parameters": [
                                {
                                    "name": "titlesize",
                                    "value": "H3"
                                },
                                {
                                    "name": "textalignment",
                                    "value": "left"
                                },
                                {
                                    "name": "style",
                                    "value": "style1"
                                }
                            ]
                        }
                    ]
                },
                {
                    "componentDefinition": "brx-reference-spa/referencespa-category-highlight",
                    "componentConfigurations": [
                        {
                            "id": "DEFAULT",
                            "content": {
                                "contentType": "CategoryHighlight",
                                "fields": [
                                    {
                                        "name": "title",
                                        "value": [
                                            "Highlight categories"
                                        ]
                                    },
                                    {
                                        "name": "connectorid",
                                        "value": [
                                            "brsm"
                                        ]
                                    },
                                    {
                                        "name": "CommerceCategoryCompound",
                                        "value": [
                                            {
                                                "fields": {
                                                    "categoryid": [
                                                        "PNB160400000000"
                                                    ]
                                                }
                                            },
                                            {
                                                "fields": {
                                                    "categoryid": [
                                                        "PNB160402010000"
                                                    ]
                                                }
                                            },
                                            {
                                                "fields": {
                                                    "categoryid": [
                                                        "PNB160401010000"
                                                    ]
                                                }
                                            },
                                            {
                                                "fields": {
                                                    "categoryid": [
                                                        "PNB250800000000"
                                                    ]
                                                }
                                            }
                                        ]
                                    }
                                ]
                            },
                            "parameters": []
                        }
                    ]
                }
            ]
        }
    ]
}
]

When converted to NDJSON (for example using this JSON to NDJSON Online Converter) it looks like this:

{"type":"document","contentType":"brxsaas:banner","fields":[{"name":"title","value":["Our team is ready for your next product"]},{"name":"content","value":["<p>example content</p>"]},{"name":"image","value":["/"]},{"name":"cta","value":["Start your next project"]},{"name":"link","value":["/content/documents/my-channel/pages/products/all"]}],"name":"next-project11","displayName":"Next Project11","path":"/content/documents/my-channel/banners/next-project11"}
{"type":"document","contentType":"brxsaas:banner","fields":[{"name":"title","value":["Brand 1"]},{"name":"content","value":["<p>Sample content</p>"]},{"name":"image","value":["/content/gallery/my-channel/banners/brand-1.jpg"]},{"name":"cta","value":[]},{"name":"link","value":["/content/documents/my-channel/pages/products/all"]}],"name":"brand-111","displayName":"Brand 111","path":"/content/documents/my-channel/banners/brand-111"}
{"type":"page","relativePath":"pages/home-222","channelId":"my-channel","name":"home-222","displayName":"Home 222","layout":"two-column","document":{"contentType":"brxsaas:content","fields":[{"name":"title","value":["My page"]},{"name":"introduction","value":["Sample introduction"]},{"name":"content","value":["Example page content"]},{"name":"image","value":["/"]},{"name":"date","value":[]}]},"containers":[{"path":"top","components":[{"componentDefinition":"brx-reference-spa/referencespa-single-banner-carousel","componentConfigurations":[{"id":"DEFAULT","content":null,"parameters":[{"name":"alignment","value":"center"},{"name":"document1","value":"banners/safe-workspace-1"},{"name":"document2","value":"banners/safe-workspace-2"},{"name":"interval","value":"10000"}]}]}]},{"path":"main","components":[{"componentDefinition":"brx-reference-spa/referencespa-titleandtext","componentConfigurations":[{"id":"DEFAULT","content":{"contentType":"titleandtext","fields":[{"name":"title","value":["Welcome to brX ContentX"]},{"name":"text","value":["Welcome to the Bloomreach Sample Front-end Application for the brX Content."]}]},"parameters":[{"name":"titlesize","value":"H3"},{"name":"textalignment","value":"left"},{"name":"style","value":"style1"}]}]},{"componentDefinition":"brx-reference-spa/referencespa-titleandtext","componentConfigurations":[{"id":"DEFAULT","content":{"contentType":"titleandtext","fields":[{"name":"title","value":[""]},{"name":"text","value":["We have tried to keep it as clean, effective and simple as possible"]}]},"parameters":[{"name":"titlesize","value":"H3"},{"name":"textalignment","value":"left"},{"name":"style","value":"style1"}]}]},{"componentDefinition":"brx-reference-spa/referencespa-category-highlight","componentConfigurations":[{"id":"DEFAULT","content":{"contentType":"CategoryHighlight","fields":[{"name":"title","value":["Highlight categories"]},{"name":"connectorid","value":["brsm"]},{"name":"CommerceCategoryCompound","value":[{"fields":{"categoryid":["PNB160400000000"]}},{"fields":{"categoryid":["PNB160402010000"]}},{"fields":{"categoryid":["PNB160401010000"]}},{"fields":{"categoryid":["PNB250800000000"]}}]}]},"parameters":[]}]}]}]}

Save the above NDJSON data to a file, for example content.ndjson.

2. Get the Project ID

The content must be imported into a specific development project. This constraint is to guarantee that all operations are performed without having any chances of affecting the live website, since all write operations are performed on the unpublished variant of a page or document associated with the development project.

Therefore the first step is to create a development project, add your channel to the project, and retrieve the project ID (for example vhusX) in the Projects app, the Site development app, or the Site Management API.

In the latter case, use the endpoint Get all channels.

{
  ...,
  "branch": "vIUy9",
  ...
}

The channel's branch property contains the project ID.

3. Import Content into the Development Project

Send a POST request to the endpoint Create content (documents and pages) in a specific project, uploading the previously saved NDJSON file as body.

When sending the content, no validation is performed against the content model.

4. Check the Status of the Import via API

First you need to get a list of all operations that were triggered via List all operations. This will return a list of UUID that represent the jobs that are running

Then, you can get the details of each of the jobs using the Get operation details endpoint.

{
  "operationId": "0f68c6d9-cfee-49ac-9cff-6d82d34ee704",
  "projectId": "vI8Xo",
  "status": "COMPLETED",
  "readCount": 6,
  "writeCount": 5,
  "skipCount": 1,
  "startTime": "[email protected]:47:00.448+0000",
  "endTime": "[email protected]:47:08.632+0000",
  "errorLog": [
    {
      "path": "pages/home",
      "error": "Item not found; nested exception is javax.jcr.ItemNotFoundException: Component definition 'hst:components/sample/single-banner-carouselZ' not found"
    }
  ]
}

5. Check the Imported Content in the UI

In the development project you can preview the imported pages and documents and approve them so that a merge can be done.

6. Merge the Project

When merging the development project, all the imported content will be published into Core.

Error Handling

In case something goes wrong during the batch import process, there is the option of deleting the project before it's merged and trying again from scratch in a new development project.