Default Content Deploy

A content deployment solution for Drupal that enables teams to export and import content continuously via JSON files without database transfers.

default_content_deploy
1,741 sites
85
drupal.org

Install

Drupal 11, 10 v2.1.4
composer require 'drupal/default_content_deploy:^2.1'

Overview

Default Content Deploy (DCD) provides a comprehensive content deployment solution for Drupal, allowing development teams to export and deploy all site content via Git. This eliminates the need to transfer databases between environments (local, staging, production).

The module serializes entities to JSON files using the HAL (Hypertext Application Language) format and stores them in a configurable content directory. Content can be exported individually, by entity type, with all references, or the entire site at once. Imports intelligently compare timestamps to only update content that has changed.

DCD is particularly valuable for CI/CD workflows where content needs to be deployed automatically alongside code changes. It supports incremental imports, force overrides, and can handle complex entity relationships including Layout Builder blocks and embedded media in text fields.

Features

  • Export individual entities, entity types, or entire site content to JSON files
  • Import content with intelligent timestamp-based comparison to avoid overwriting newer content
  • Export entities with all their references recursively (media, files, taxonomy terms, users, etc.)
  • Support for Layout Builder inline blocks and referenced block content
  • Export dependencies embedded in processed text fields (images, media, entities in CKEditor content)
  • Download exported content as a compressed tar.gz archive via the admin UI
  • Upload and import content from tar.gz archive files
  • Force override option to revert all content to the state defined in export files
  • Drush commands for all operations enabling CI/CD automation
  • Batch processing for large content sets with progress tracking
  • Incremental import mode that skips unchanged content based on timestamps
  • Event system for customizing export/import behavior via event subscribers
  • Skip specific entity types from export/import operations
  • Delete content during import (mark exported entities for deletion)
  • Preserve entity IDs option for specific deployment scenarios
  • Search API integration submodule for tracking and incremental exports
  • Cron-based garbage collection for orphaned batch items

Use Cases

Development Team Content Synchronization

Multiple developers working on a project can export content to the Git repository. Each developer exports their changes with 'drush dcdes', commits the JSON files, and others import with 'drush dcdi' after pulling. This eliminates the need to share database dumps and ensures content changes are version controlled alongside code.

CI/CD Automated Content Deployment

In a continuous deployment pipeline, content can be automatically deployed alongside code. The deploy script includes: git pull, drush updb -y, drush cim -y, drush cr, drush dcdi -y. This ensures staging and production environments have consistent content without manual intervention.

Default Content for Site Installation

Package default content with a custom installation profile or module. Export initial content once, commit to the repository, and have it imported automatically on every fresh installation. Perfect for demo sites, starter kits, or distribution packages.

Content Staging Workflow

Content editors create content on a staging environment. Using the Export UI or Drush commands, content is exported to files. After review, these files are deployed to production via Git, where they're imported. This provides a controlled content promotion workflow.

Site Migration and Backup

Export the entire site's content with 'drush dcdes' before major updates or migrations. The JSON files serve as a portable backup that can be imported into any Drupal installation with matching configuration, regardless of database differences.

Incremental Content Sync with Search API

Using the Search API submodule, content changes are automatically tracked. Only modified entities are exported, making it efficient for sites with large amounts of content. The Search API backend handles the complexity of determining what needs to be exported.

Tips

  • Place the content directory outside the document root for security (e.g., ../content relative to web root)
  • Use --verbose flag with Drush commands to see detailed progress and entity-level information during import/export
  • For large sites, use the --changes-since option to export only recently modified content
  • Export users first when setting up a new environment to ensure UUID synchronization for admin and anonymous users
  • The _thumbs folder contains lightweight metadata files for faster incremental import scanning
  • Use 'drush dcd-entity-list' to see all available entity types before exporting
  • Commit exported content files to Git with meaningful commit messages for traceability
  • Test imports on a staging environment before deploying to production
  • The Search API submodule provides automatic export on entity save, ideal for continuous content export workflows

Technical Details

Admin Pages 3
Default Content Deploy settings /admin/config/development/dcd

Configure global settings for content export and import operations including the content directory path, entity types to skip, and serialization options.

Default Content Deploy - Import /admin/config/development/dcd/import

Import content from JSON files stored in the content directory or from an uploaded archive file. Equivalent to drush dcdi command.

Default Content Deploy - Export /admin/config/development/dcd/export

Export content to JSON files in the content directory or download as a compressed archive. Equivalent to drush dcde/dcder/dcdes commands.

Permissions 2
Import content

Allows user to import any exported content via UI. It will overwrite existing content. Restricted access permission.

Export content

Allows user to export any content via UI. Restricted access permission.

Hooks 2
hook_hal_type_uri_alter

Alters the HAL type URI during serialization. DCD uses this to create portable URIs in format [ENTITY_TYPE]/[BUNDLE].

hook_hal_relation_uri_alter

Alters the HAL relation URI during serialization. DCD uses this to create portable URIs in format relation/[ENTITY_TYPE]/[BUNDLE]/[FIELD].

Drush Commands 9
drush default-content-deploy:export <entity_type>

Exports a single entity or group of entities without references. Exports entities as JSON files to the content directory.

drush default-content-deploy:export-with-references <entity_type>

Exports entities along with all their referenced entities recursively. Includes media, files, taxonomy terms, users, and other referenced content.

drush default-content-deploy:export-site

Exports all content on the entire site. Useful for full site backups or initial content deployment setup.

drush default-content-deploy:import

Imports content from JSON files in the content directory. Creates new entities or updates existing ones based on UUID matching.

drush default-content-deploy:uuid-info <entity_type> <id>

Displays the UUID value of a specific entity. Useful for identifying entities for export.

drush default-content-deploy:entity-list

Displays all content entity types available on the site. Useful for determining valid entity_type arguments.

drush default-content-deploy:get-last-import-timestamp

Get the last import timestamp stored in state for a content folder. Used for incremental import tracking.

drush default-content-deploy:set-last-import-timestamp <timestamp>

Set the last import timestamp in state for a content folder. Useful for resetting incremental import state.

drush default-content-deploy:sync-thumbs

Synchronize the thumbs (metadata) folder from the content directory. Creates optimized metadata files for faster incremental imports.

Troubleshooting 7
Import fails with 'Translated field denormalization creates duplicate values' errors

Apply the patch from https://www.drupal.org/files/issues/2023-04-05/2904423-90.patch to address the HAL module issue with translated fields.

Entity timestamps are modified during import on Drupal 10

Apply the core patch from https://www.drupal.org/project/drupal/issues/2329253 to preserve entity timestamps. Drupal 11 includes this fix natively.

Exported content files are accessible from the web

Move the content directory outside the document root (recommended) or add .htaccess (Apache) or nginx location rules to deny access to JSON files in the content directory.

Referenced entities are not being exported

Use 'drush dcder' instead of 'drush dcde' to export with references. Check that the referenced entity types are not listed in 'skip_entity_types' configuration.

Import skips entities even though they were exported

The import compares timestamps and skips entities where the file is older than the database. Use --force-override flag to import regardless of timestamps.

Entity IDs change after import

By design, DCD uses UUIDs for entity identification. Entity IDs may change during import. If preserving IDs is critical, use the --preserve-ids flag (may cause conflicts with existing entities).

Conflict with better_normalizers module

The better_normalizers module is incompatible with DCD. Remove it before using Default Content Deploy.

Security Notes 5
  • Exported JSON files may contain sensitive data. Always place the content directory outside the document root or protect it with web server configuration.
  • The import permission allows overwriting any existing content. Grant this permission only to trusted administrators.
  • User password hashes are included in user entity exports. Ensure the content directory is not publicly accessible.
  • When importing from uploaded archives, validate the source to prevent importing malicious content.
  • The module operates with administrator privileges during import/export to access all entity data.