Topics

On this page

Last updated on Jan 2, 2025

AEM to WordPress: Pre-migration

As the name suggests, the pre-migration phase involves all the preparatory work required before the actual migration begins. This includes auditing the existing system, cleaning data, taking backups, mapping the ecosystem (including content), setting up development environments, and more.

Getting the technical setup in place

In this chapter, we’ll cover the essential technical groundwork for your AEM to WordPress migration. From setting up your development environment(s) to organizing assets and taking backups, every step is designed to set the stage for a successful transition to WordPress.

Setting up local, testing, and live environment(s)

Setting up a local development environment is your crucial first step when migrating from AEM to WordPress. We’ll now walk you through the process of creating a local WordPress installation for development, testing, and staging purposes for your migration project.

Local WordPress installation setup

To successfully migrate from AEM to WordPress, it’s important to have a proper local setup that mirrors your final environment as closely as possible. This section will focus on establishing the basic local environment and tools needed for the migration.

Choosing a local WordPress setup method

When setting up your local WordPress installation, there are different methods you can use depending on your preferences and technical requirements.

Using Docker

Docker allows you to create a standardized environment that mimics production, making it an ideal choice for teams. Follow these steps if you wish to use Docker:

  1. Install Docker and Docker Compose.
  2. Set up a Docker Compose file to define your WordPress, MySQL, and other services.
  3. Run Docker Compose to get the environment up and running:
    docker-compose up -d

This setup ensures consistency and can be versioned easily for different developers.

Using local tools

If you prefer a simpler setup, you can use tools like LocalWP or MAMP to install WordPress locally. These tools offer a user-friendly interface and reduce the need for manual configuration, making them ideal for less technical users or for quickly setting up an environment.

A side note: Setting up a multisite installation

If you have multiple sites, like example.com and blog.example.com, setting up a WordPress Multisite can be highly beneficial. You can structure your multisite in one of two ways: subdirectory or subdomain. Let’s see each in detail

Subdirectory vs subdomain structure

A subdirectory structure is used when your sites are part of the same domain, like example.com/site1 or example.com/site2.

In wp-config.php, add the following lines: define('WP_ALLOW_MULTISITE', true);

A subdomain structure is used when your sites are in separate subdomains, like site1.example.com or site2.example.com.

This setup requires DNS configuration to point each subdomain to your local server.

Once you’ve your local WordPress environment set up, it’s time to customize your WordPress directory.

Preparing the wp-content directory

To prepare your environment for migration, it’s essential to customize the default wp-content directory based on your project’s requirements. Below is a structured approach to ensure your local environment is ready for migration:

Remove default content

The default wp-content directory contains the standard themes and plugins included with a fresh WordPress installation. These are not necessary for your project, so you should remove them:

“`rm -rf wp-content“`

By deleting this directory, you are clearing out all default themes and plugins to make space for the custom setup that will be used during the migration.

Clone the project repository

Next, replace the default wp-content with your project-specific content by cloning the appropriate repository. This repository will serve as the foundation for your migration:

“`

# Clone the repository

git clone git@github.com:YOUR_ORG/YOUR_PROJECT.git wp-content

“`

This repository should contain:

By setting up this repository, you ensure that your local environment is ready with all necessary components, which will support the migration activities effectively.

Setting up a version control system (and a branching strategy)

With your local environment ready, the next step is effectively managing your code changes using GitHub or some other version control system. This ensures all development work is organized and easily accessible for collaboration. Here’s how to go about this:

git checkout master

git pull origin master

git checkout -b migration-branch

This allows you to keep all changes organized and easily accessible for collaboration within your team. This ensures that your work remains separate until it is ready to be merged.

Avoid the develop branch: Avoid branching from develop unless explicitly required, as it might contain changes not yet present on production. Doing so ensures that your branches are always stable and aligned with production.

Push changes regularly: Regularly push your changes to GitHub to keep them backed up and shared with your team

git push origin migration-branch

Use GitHub pull requests to ensure all changes are reviewed and quality-checked before merging. This helps maintain code quality and allows for team feedback.

Staging environment setup

Once your local environment is ready and changes have been committed, it’s time to set up a staging environment. (Your hosting provider may also help with this, so get touch with them.)

Pay attention to these things when working with your staging environment:

Mirror production setup

Set up a staging environment that closely mirrors the production setup.

Sort staging URLs

The staging environment should include the same database and configuration as production but with staging-specific URLs.

Build a staging workflow

Push any code you write or changes you make to the staging environment to validate before going live.

Also perform QA testing on the staging environment, including link checks, media availability, and functionality.

We’ll discuss QA in a later section in detail.

Live environment setup

The final AEM to WordPress migration step is deploying your staging environment instance to the live environment. But before you do (when we get to the launch), keep these in mind:

Key considerations when setting up your different migration environments:

This structured approach to the different environments and development best practices help ensure a smooth migration process and minimizes risks associated with the transition from AEM to WordPress.

Backing up your AEM setup

Backing up your Adobe Experience Manager (AEM) setup is key to making sure you don’t lose your hard work and can recover quickly if something goes wrong. Let’s dive into how each piece of your AEM setup can be backed up step by step.

Images, media, and videos

AEM stores digital assets like images, media, and videos in the Digital Asset Management (DAM) repository. Here’s how you can back these up:

Export method

Assets are exported as compressed files (e.g., ZIP format) to preserve their structure and metadata.

Storage location

Typically, these assets are saved in the AEM repository (CRX) or external storage solutions like Amazon S3 to ensure safety.

Content 

Your content, including web pages and structured data, resides within the repository.

Export method

AEM’s Package Manager can be used to create packages containing pages, templates, and related assets. These packages can be exported in .zip or .xml formats for easy restoration when needed.

Users

User data such as login credentials and profiles is also crucial for maintaining a seamless user experience when migrating.

Backing up users

If user data is stored in AEM, you can export it using the User Management Console, typically in formats like .json or .xml.

External systems

If you’re using an external identity provider like LDAP, ensure that separate backups of those systems are managed, usually through database exports or dedicated tools provided by those systems.

Metadata

Metadata includes information like keywords, captions, and technical specifications associated with assets.

Backup process

Metadata is backed up alongside digital assets. Using AEM’s Metadata Schema Forms, you can export metadata in .json format or as part of asset packages created with the Package Manager. This ensures compatibility when restoring or migrating your assets.

Analytics

Analytics data is often collected and stored in external systems like Adobe Analytics, which requires its own approach.

Backup procedure

Since this data resides outside AEM, it should be backed up in coordination with the analytics provider. Adobe Analytics, for example, allows for exporting reports in .csv or .json formats. It’s important to ensure that all essential analytics data is captured during the backup process.

Feature/integration configurations

Custom features and integrations must be preserved to maintain site functionality. So backing up their configurations is another key step.

Code backups

Store custom features in Git repositories such as GitHub or GitLab. Create snapshots of branches and tags as a single backup process to maintain a complete record of the current state.

Configurations

Integration configurations should be exported from AEM using the Package Manager or saved as .yaml or .xml files, ensuring they are ready to be restored when needed.

Forms data

Forms are a key part of interacting with users, and their data needs careful handling.

Forms and configurations

Export forms from AEM as .zip packages that include all form fields and configurations.

Form submission data

If form submissions are stored externally, export them as .csv or .sql files. Perform a comprehensive backup using database management tools to ensure all data is safely preserved.

Additional considerations when backing up your AEM instance

Workflows

Back up your workflows using AEM’s Package Manager. Export workflow models and instances as .zip packages to retain a record of active workflows.

Taxonomy and tags

Export content classification data, such as taxonomy and tags, using CRXDE Lite or AEM Package Manager. This will help retain the original structure and classification during migration or recovery.

Securing backups

Once you’ve backed up all your AEM components, it’s equally important to secure the backed-up data. Utilize secure cloud storage solutions, such as AWS S3, with encryption enabled. Regularly verify the integrity of these backups to prevent data corruption, and store at least one backup version offsite to mitigate risks.

In summary, creating backups for AEM is about more than just copying data—it’s about creating a strategic approach that ensures seamless recovery and keeps your environment running smoothly in case of an issue.

Preparing your AEM content for migration

Getting content ready is one of the most important steps for a smooth migration from AEM to WordPress. Here, we’ll dive into content mapping, the process of identifying how existing AEM content transitions to WordPress. This ensures we preserve your content structure, relationships, and user experience effectively. But before that we’ll prepare the content for migration. 

Cleaning data before backing up 

The data cleanup process is all about getting rid of what’s unnecessary, standardizing what’s inconsistent, and making sure everything is optimized for migration.

Identify what stays and what goes

Start by listing out all your content using AEM’s Content Inventory Reports. This will help you decide which pages, blog posts, and other content pieces are worth migrating. Don’t forget to archive anything that is outdated or irrelevant to avoid clutter in WordPress.

Remove duplicate or outdated content

Use AEM tools like Version Purging to delete older, redundant versions of content. This keeps things neat and prevents outdated material from moving over to your new site.

Standardize metadata and format

It’s a good idea to review and update metadata, like title tags and descriptions, so they align with your SEO goals. Missing alt texts or keywords? Now’s the time to add those.

Use the AEM Link Checker to detect and correct broken internal links. Ensuring that all links are updated before migration makes the transition smoother and prevents broken links on your new WordPress site.

Preparing digital assets for migration

Once your content is cleaned up, it’s time to focus on your digital assets like images, videos, documents, and other files. This step ensures that your assets are organized and optimized for migration.

Consolidate asset storage

Make sure all your assets are centralized in the AEM Digital Asset Management (DAM) system. Keeping everything in one place makes it easier to move and track assets during migration. Read AEM DAM overview for more.

Optimize file sizes

Compress images and videos to ensure they’re web-friendly. You can use tools like TinyPNG for image compression and HandBrake for video compression. Optimizing assets not only saves space but also helps improve the performance of your new WordPress site.

Clean up tags and metadata

Go through and standardize tags and metadata for your assets. Having a consistent tagging system makes it easier to find what you need later on. Tools like AEM’s Tagging Interface are helpful for cleaning up and applying new tags.

Optimize folder structure and naming conventions

Before migrating, make sure assets are stored in a clear, logical folder structure. Group assets by type or campaign, and use consistent naming conventions. Descriptive file names make it easy to identify assets, think homepage-banner.jpg instead of img123.jpg.

Content mapping

Once you’ve cleaned up your data, it’s time to work on content mapping. Content mapping is like creating a blueprint for how each part of your AEM content fits into WordPress. Below, we’ll show you how we can understand the data exported from AEM, map it to WordPress, and even automate the whole process with custom scripts.

Exporting AEM data

The first step is to get our content out of AEM. Luckily, AEM provides a few different ways to do this:

Here’s a sample of AEM export data (in JSON Format)

This is what your AEM content looks like once it’s exported using the JSON format:

{
  "homepage": {
    "jcr:primaryType": "cq:Page",
    "jcr:content": {
      "jcr:primaryType": "cq:PageContent",
      "jcr:title": "Welcome to Our Site",
      "jcr:description": "A brief description of the homepage",
      "sling:resourceType": "project/components/page/home",
      "header": {
        "jcr:primaryType": "nt:unstructured",
        "title": "Header Title",
        "subtitle": "Welcome to our website"
      },
      "mainContent": {
        "jcr:primaryType": "nt:unstructured",
        "text": "This is the main content area of the homepage."
      }
    }
  }
}

Content mapping from AEM to WordPress

Let’s break down the AEM export data that we just saw and see how it maps over to WordPress. First there’s some page level information.

Page level information

The “homepage” key represents the whole page. It’s like the foundation, we’ll map this to a WordPress Page.

The “jcr:title”: “Welcome to Our Site” is straightforward, it becomes the title of the WordPress page.

“jcr:description” can either be used as an excerpt in WordPress or even as the meta description if we’re using an SEO plugin like Yoast.

Sections within the page

The “header” node in AEM contains a “title” and a “subtitle”. In WordPress, we could create custom fields to store this information. Plugins like Advanced Custom Fields (ACF) are perfect for this kind of data because it allows us to easily add fields like “Header Title” and “Header Subtitle”.The “mainContent” holds the main text on the page, and this content will go directly into the WordPress Editor, it’s the core content users will see.

Here’s a mapping table for easy reference:

AEM Data PropertyWordPress MappingDetails
“jcr:title”Page TitleThis becomes the WordPress page title.
“jcr:description”Excerpt / Meta DescriptionUseful for SEO (e.g., via Yoast plugin).
“header.title”Custom Field (Header Title)Created with ACF for easy management.
“mainContent.text”Main Page ContentMaps to the WordPress Editor.

Automating content mapping with custom scripts

Now, let’s talk about automating this process. If we had to do all this manually, it would take forever, especially when dealing with thousands of pages. This is where custom scripts come in handy. You can use a language like JavaScript or Python to automate the migration.

Here’s a sample JavaScript migration script:Here’s an example of how you can do it with JavaScript and Axios. We’ll use Node.js to read the AEM JSON and send the content to WordPress.

const axios = require('axios');
const fs = require('fs');

// Load AEM data from JSON file
fs.readFile('aem_content.json', 'utf8', (err, data) => {
  if (err) {
    console.error('Error reading the AEM JSON file:', err);
    return;
  }

  const aemData = JSON.parse(data);
  const homepage = aemData?.homepage?.['jcr:content'];

  if (!homepage) {
    console.error('Invalid AEM data structure.');
    return;
  }

  // Prepare data for WordPress
  const wpData = {
    title: homepage['jcr:title'],
    content: homepage?.mainContent?.text || '',
    excerpt: homepage['jcr:description'],
    status: 'publish'
  };

  // WordPress REST API endpoint
  const wpApiUrl = 'https://your-wordpress-site.com/wp-json/wp/v2/pages';
  const username = 'your_username';
  const password = 'your_application_password'; // Create an application password in WordPress

  // Encode credentials for Basic Authentication
  const encodedCredentials = Buffer.from(`${username}:${password}`).toString('base64');

  // Send data to WordPress using Axios
  axios
    .post(wpApiUrl, wpData, {
      headers: {
        'Authorization': `Basic ${encodedCredentials}`,
        'Content-Type': 'application/json'
      }
    })
    .then(response => {
      if (response.status === 201) {
        console.log('Page created successfully:', response.data);
      } else {
        console.error('Failed to create page. Status:', response.status);
      }
    })
    .catch(error => {
      console.error('Error creating the page:', error.response ? error.response.data : error.message);
    });
});

Metadata mapping

Map AEM’s custom metadata (like SEO tags, authors, publication dates) to fields in WordPress, possibly using plugins like Yoast SEO.

Mapping content hierarchies and URL structures

 It’s important to keep URL structures intact for SEO. For instance, an AEM URL like /services/cloud-solutions should ideally be preserved in WordPress to avoid breaking links.

(We will see these in detail in the migration section.)

AEM to WordPress content mapping elements

AEM ComponentWordPress EquivalentAction Needed / ToolsDetails
Page Nodes (cq:Page)Pages or PostsMap AEM pages to WordPress Pages or PostsUse the WordPress REST API to create new Pages or Posts. Preserve titles, slugs, and metadata.
Structured Content (cq:PageContent)Custom Post Types (CPTs)Use Custom Post Types UI or custom code to define CPTsFor content that doesn’t fit WordPress standard posts/pages (e.g., Locations, Policies).
Digital Assets (DAM)Media LibraryUse the WordPress Media Library REST API to uploadDownload assets from AEM DAM, then upload to WordPress and update content links.
Metadata (jcr:description, dc:title)Yoast SEO Metadata or Custom FieldsMap AEM metadata to SEO fields via Yoast SEO pluginUse Advanced Custom Fields (ACF) if metadata requires custom handling beyond SEO.
Images, Media, VideosMedia LibraryUpload via REST API and link in contentMake sure to preserve ALT text, titles, and descriptions for accessibility and SEO.
Tags and CategoriesTags and CategoriesDefine tags and categories in WordPressReflect the categorization and tagging structure from AEM to ensure content remains discoverable.
Sub-pages / Page HierarchiesParent-Child Page RelationshipsMaintain relationships using WordPress Page attributesUse a hierarchical structure in WordPress to retain SEO and user navigation paths.
Content FragmentsReusable Blocks or CPTsCreate Reusable Blocks in GutenbergUse Custom Post Types if the content fragment is used across multiple sections but requires custom fields.
Embedded Components (sling:resourceType)Gutenberg Blocks or ShortcodesDevelop custom Gutenberg blocks or use shortcodesConvert AEM-specific components (e.g., carousels, callouts) to Gutenberg blocks for better editing flexibility.
Forms (AEM Forms)Gravity Forms or Contact Form 7Use a form builder plugin to recreate the formsMigrate submission data as CSV and import into Gravity Forms or another plugin. Preserve all form fields and logic.
User RolesWordPress User RolesUse User Role Editor to create custom roles if neededMap AEM user roles to WordPress (e.g., Author, Editor). Custom roles may need to be created to match AEM capabilities.
Permissions (rep:Policy)Custom CapabilitiesUse User Role Editor or Members pluginIf AEM has specific access control, create custom roles with equivalent permissions in WordPress.
URL StructurePermalink Structure and 301 RedirectsUpdate permalinks to match AEM URLs or use a Redirection pluginEnsure consistent URLs for SEO purposes. Create 301 redirects for any changes.
Workflows (cq:workflow)Editorial Workflows (via plugins)Implement using plugins like Edit Flow or PublishPressWorkflows in AEM can be recreated to manage content creation and approval processes in WordPress.
Taxonomy (tags, categories)Custom TaxonomiesUse Custom Taxonomies to replicate AEM content categoriesPreserve the same tagging and categorization schema for consistent content organization.
Analytics (Adobe Analytics)Google Analytics or another Analytics PluginEmbed tracking codes into theme files or use Site KitExport historical data from Adobe Analytics to maintain reporting continuity. Implement new tracking tags in WordPress.
Experience FragmentsReusable Content BlocksConvert to Gutenberg Reusable BlocksExperience fragments from AEM can be turned into reusable blocks for use in various parts of the site.
Personalization (targeted components)Personalization Plugins or custom codingUse WP Engine Personalization or custom scriptsAEM personalizations need to be replaced by plugins or custom logic for targeted content delivery in WordPress.
Language Copies / TranslationMultilingual Plugin (e.g., WPML, Polylang)Use a plugin to manage language copies and translationsEnsure that translated pages in AEM are properly mapped to translated pages in WordPress using a multilingual plugin.
Redirect RulesRedirection PluginSet up using the Redirection Plugin in WordPressMigrate existing AEM redirect rules to WordPress to maintain SEO and user experience.
Scripts and IntegrationsCode Snippets Plugin or in Theme FilesAdd tracking codes, third-party integrations manuallyScripts for services like analytics, CRMs, or marketing tags should be placed in theme files or using plugins like Insert Headers and Footers.
Embedded Video and MediaGutenberg Video Block or ShortcodeInsert media using Gutenberg video blocks or via oEmbed URLsEnsure that all media URLs are preserved, and use responsive video blocks for mobile compatibility.
DAM RenditionsImage Sizes (Responsive Images)Upload different image sizes to WordPress Media LibraryReplicate AEM DAM renditions by generating multiple image sizes for different screen resolutions using WordPress.
Forms Data (Submitted Responses)Gravity Forms EntriesExport form submissions from AEM and import to Gravity FormsEnsure data is imported properly to preserve user information and past submissions.
Author InformationCustom User MetaUse ACF to create additional fields for author detailsAEM’s author data like biographies can be added to WordPress using custom user meta fields or ACF.
Vanity URLs (vanityUrl property)Custom RedirectsUse Redirection Plugin for vanity URLsSet up vanity URLs in WordPress to redirect to their target pages, preserving any custom short URLs.


Credits

Authored by Disha Disha Disha Sharma Author , Shreya Shreya Shreya Agarwal Author