I have some entries saved in a JSON file with the standard format that is created with export functionality (expanded). How can I import the entries from this JSON file back to my CMS?

Feed Me seems to be a complex streamline solution, but all I need is a single-time import. Craftimport only allows XML and seems outdated and unmaitained.

2 Answers 2


You can write a simple migration that uses Craft's API to create entries programmatically. You can generate a new migration with the migrate/create console command:

php craft migrate/create content_import

This will create a new PHP file in the migrations/ folder. You can put the migration code inside the safeUp method. To execute the migration:

php craft migrate/up

Inside the migration, you need access to your JSON. You can put the entire JSON string inside the migration, but I usually don't want to have that much data in my source control. Instead, I like to put the JSON inside the migrations/ folder and load it inside the safeUp method:

$json = file_get_contents(__DIR__ . 'data.json');
$rows = json_decode($json, true, 512, JSON_THROW_ON_ERROR);

This means you need to place this file in the production server manually, but that's fine since it's a one-time operation.

Once the JSON is loaded, you can create entries through the Elements service:

$contentSection = \Craft::$app->sections->getSectionByHandle('myContentSection');
$contentEntryType = $contentSection->getEntryTypes()[0];

foreach ($rows as $row) {
    $entry = new \craft\elements\Entry();
    $entry->sectionId = $contentSection->Id;
    $entry->typeId = $contentEntryType->id;
    $entry->enabled = true;
    $entry->title = $row['title'];
    // Set more properties as needed, i.e. slug, postDate, etc.

        'body' => $row['body'],
        // Set other custom fields

    $success = \Craft::$app->elements->saveElement($entry);
    if (!$success) {
        \Craft::error('Couldn’t save the entry "' . $entry->title . '"', __METHOD__);
        return false;

To test the migration repeatedly during migration, you need to modify the safeDown method. I like to put in code that deletes all the imported entries (careful, the following will delete all entries in the given section):

$content = \craft\elements\Entry::find()

foreach ($content as $entry) {
    \Craft::$app->elements->deleteElement($entry, true);

Then you can redo the migration for testing purposes like this:

php craft migrate/redo 1

This may look complicated, but is pretty simple and quick once you've done it a few times. If this seems daunting, Feed Me is probably the better option.


Personally, I'd use FeedMe. It's excellent. If you don't need it again just remove it after you have used it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.