How to migrate content between apps

Enonic version: 7.14.0


We’re starting to rewrite an application. In the old app we have a product content type. In the new app we also have a product content type with some overlap with the old product. Some fields are new, some are the same and some are removed.

We would like to migrate the old data over to the new product. What would be a good way to do that? Some of the data we want to keep is references to other content that we also need to migrate one to one. I was thinking about exporting all the product content from old site and doing a search replace to change content type and app name and reimport to another site. But it fear this will be a nightmare

Hi Tommy,

I think I would just change the shape of the content, keeping the id (using nodeLib to be able to change the type).

Run and re-run the migration locally in development until you are sure that it works as intended. Maybe you can write some code that visits all pages of a content type to ensure that you’re not getting any status 500-errors returned.

If you’re using TypeScript and XP Codegen Plugin, you can just copy the old TypeScript type to a separate temporary file. Then you can write a typesafe migration function from the old shape to the new shape.

In the past I’ve also done migrations where I create a new content (instead of updating the existing one).

I have created a new repo where I store objects with the old id and the new id. Then I can iterate over all the new content and update the references to the new ids.

– Tom Arild



Migrating data is not too easy. We have not migrated the way you describe - all contents between two apps, but we had for a while two apps and moved one or two content-types and parts between them. This as you probably know changes the type value even if the content type name is the same, as it is prepended by the app name. As Tom suggests, use the node API to manipulate this value as it is stored as a string and very easy to change - do a query for old type value, replace with new value. If I’m not mistaken this will place the changed content in draft mode, so you should before that check if it is published or not, if it was you re-publish it. We check if it was published before modifying the content, and do it with the .diff() function you have on repo connections. We do the same when moving parts (or renaming parts). But to be honest all this is very complicated labour. But after that code has run you should instantly see your contents being of new types, we made sure to have different icons for the content types so it was easy to verify the change. But for our migrations the data didn’t change, so that would require even more coding.

We decided to build an admin tool for migrations, so we could install it where needed and run it manually when needed. Made the threshold for doing migrations a bit bigger, but easier to roll out on multiple domains. It has become a bit of a beast of code that no one wants to update though, but it happens we move data within content types and parts around too. Usually we practice keeping old input until migration is done, we label it “DEPRECATED” and then we add the new data-field, update the code to read both (prefer new value) and then after running the script we can remove old input and clean up the code.

Really wish this could be smoother in the future.

1 Like