Elementor migration

Elementor to Next.js: Getting Your Content Out of the Builder and Into Real Fields

Export an Elementor site the usual WordPress way and you get the words without the page: headings and paragraphs flattened into a lump, with the layout, buttons and images left behind. The real page lives somewhere else. Here is where, and how to move it to Next.js without losing a sentence.

October 8, 2026 · 9 min read

The short answer

Elementor stores each page as JSON in a post meta field called _elementor_data, not in the normal post content. Moving to Next.js means reading that JSON, pulling the text, images and links out of each widget, turning Theme Builder templates into page types, rebuilding popups and forms as components, and converting global colors and fonts into design tokens.

On this page
  1. The page you edit is not the page WordPress stores as content
  2. Inside _elementor_data: containers all the way down
  3. Widget by widget: what carries over and what gets rebuilt
  4. Theme Builder parts become page types
  5. Popups and forms: move the behavior, not the markup
  6. Global colors and fonts, turned into design tokens
  7. The Elementor exit, in order
  8. When staying on Elementor is the better move

The page you edit is not the page WordPress stores as content

In a plain WordPress page, the content field holds the page. Elementor works differently. Its source code saves the layout as JSON in a post meta key named _elementor_data, marks the page as builder-made with _elementor_edit_mode, and keeps page-level settings in _elementor_page_settings. Every time you save, Elementor also writes a plain-text copy of the page into the ordinary content field, with dynamic content stripped out, so search and excerpts have something to read.

That plain copy is why a standard export looks almost right and is quietly wrong. You get the words in order, but not which words were a button, which image sat beside which paragraph, or which block was a testimonial. The standard REST routes are no better, because the WordPress handbook lists metadata among the things the API shares only with authenticated requests. A clean migration reads the JSON itself, from a database export or a small script on the old site.

Inside _elementor_data: containers all the way down

Elementor's developer documentation describes the format plainly. Each element has an id, an elType that says what it is, a settings object with everything you set in the panel, and an elements array holding its children. Older pages nest sections, columns and inner sections; newer ones nest containers. Widgets sit at the bottom of the tree, each with a widgetType such as heading, text-editor, image or button.

Extraction is a walk down that tree. A script visits every element in reading order, ignores the purely visual settings (padding, borders, motion effects), and collects what a reader would notice: heading text and level, paragraphs, images with their alt text, links and button labels, list items, and the items inside tabs and accordions. What comes out is a clean sequence of content blocks, which is then mapped to the fields of the matching page type in Athena CMS.

The tricky part is intent. A heading widget set in huge type might be the page's real H1 or a decorative number. Three image boxes in a row might be services, team members or logos. A script can find them; a person decides what they mean. On a site with a few saved templates that decision is made once per template. On a site where every page was built by hand, it is made page by page, which is the main reason Elementor sites take longer and cost more than block-editor sites, as the cost guide explains.

Widget by widget: what carries over and what gets rebuilt

Common Elementor widgets and where they land in Next.js
Where the content sitsIn the Next.js site
HeadingTitle text and HTML tag in settingsA real heading in the template, with the level corrected
Text EditorHTML in the editor settingRich text field, cleaned of inline styles
ImageImage object with media ID and URLMedia moved with alt text, served through next/image
ButtonLabel and link settingsLink or call-to-action field
Icon ListRepeater of items with text, icon and linkList field or structured items
Tabs and AccordionRepeater of titles and contentFAQ or tab component with editable items
Testimonial and carouselsSlides with quote, name and imageTestimonial entries, shown however the design needs
Form (Pro)Field definitions, actions after submitRebuilt form with server-side validation
Add-on pack widgetsEach vendor's own settings shapeRead case by case, then rebuilt
Shortcode widgetWhatever another plugin outputsReplaced by the feature itself, or dropped

Add-on packs deserve a warning. Every widget pack stores its settings in its own shape, so a site with two or three packs needs a reader for each. The upside is that migration is often the moment those packs disappear for good: the one carousel that justified a whole plugin becomes one component. The page builder vs Next.js comparison explains why that matters for speed.

Theme Builder parts become page types

Elementor Pro's Theme Builder is where an Elementor site keeps its skeleton: the header, the footer, the single-post template, the archive template, sometimes a separate template for each custom post type. Each one carries display conditions that decide where it appears. When two headers fight over the same pages, those conditions are usually why.

In Next.js, these map almost one to one onto things the framework already has. The header and footer become a shared layout. Single and archive templates become route templates for each page type. Dynamic tags, the Elementor feature that pulls a post title or a custom field into a widget, become plain references to fields in the content model. The display conditions turn into routing rules written in code, which is a relief: they stop being a hidden setting and become something anyone can read.

  • Header and footer templates become one layout, edited in Athena through menu and contact fields.
  • Single templates for posts, services or projects become one page type each, with fields matched to their dynamic tags.
  • Archive and loop templates become listing pages with real pagination and filters.
  • The 404 template becomes the site's not-found page, finally consistent with the rest of the design.

If your site runs on Hello Elementor, almost everything visible came from the Theme Builder, so this step is most of the job. The theme-specific walkthroughs are Hello Elementor to Next.js and, for sites on the theme Elementor is moving into maintenance mode, Hello Biz to Next.js.

The third option

Athena CMS, with AI agents on staff.

Not a theme and not a blank Next.js repo. The content system we put behind every custom site: plain fields, a real preview, every version kept, and AI agents that handle the chores a plugin only nags you about.

and 12 more agents. Two come with Athena; the rest are monthly add-ons.

The Athena CMS editor: plain fields with AI rewrite, a Publish box and revisions

Popups and forms: move the behavior, not the markup

Popups are stored as templates of their own type, each with display conditions, triggers (on page load, on scroll, on exit intent) and advanced rules about how often to show. Migrating them is mostly a business question. List every popup, check which ones still run a live offer, and rebuild only those, as components that load when triggered rather than on every page. Popups that announce a sale from two summers ago can retire quietly.

Forms carry more weight, because leads depend on them. For each Elementor form we record the fields, the validation, every action after submit (email, webhook, CRM or email-marketing connection) and the confirmation message. The Next.js version is rebuilt with server-side validation and spam protection that does not punish real customers, a topic covered in why WordPress forms get spammed. If past entries matter to you, export them from WordPress before launch; they do not move with the form.

Migrate what the popup did for the business, not what it did to the page.

Global colors and fonts, turned into design tokens

Elementor keeps site-wide styles in a kit: a special template whose ID is stored in the elementor_active_kit option. Its settings hold the global colors (four system colors named Primary, Secondary, Text and Accent, plus any custom colors you added), the global typography in the same system-plus-custom pattern, button and form styles, and the breakpoints.

That is a gift for a migration, when it was used properly. Global colors become color tokens, global fonts become typography tokens, and the breakpoints inform the responsive layout. Fonts are then self-hosted through next/font, so text no longer waits on a third-party server. The catch is that many Elementor sites set colors widget by widget instead of using the globals, which leaves a dozen near-identical blues scattered through the JSON. Part of extraction is collecting every color actually used, merging the near-duplicates and agreeing on a short palette.

The Elementor exit, in order

  1. 1

    Inventory

    Every page, post, template, popup and form, with the Elementor and Pro plan in use, every add-on pack, and every URL Google knows. Start at the free site audit.

  2. 2

    Export the data

    A database export or a script that reads _elementor_data for every page and every elementor_library template, plus the active kit's settings.

  3. 3

    Classify the layouts

    Group pages by the template or pattern they follow, decide what each widget means, and define the page types and fields in Athena.

  4. 4

    Extract and map

    Walk each page's JSON, pull the content in reading order, and load it into the matching fields, with images moved and alt text kept.

  5. 5

    Rebuild the skeleton

    Header, footer, page templates, popups that earn their place, and every form, built in Next.js from the design tokens.

  6. 6

    Redirect and compare

    Every old URL kept or redirected, each new page checked against the Elementor original on a preview address, then launch.

Search protection runs through every step rather than at the end; the full method is in migrating without losing SEO, and the time each step takes is discussed in the migration timeline.

When staying on Elementor is the better move

Elementor is good at what it was built for. If your marketing team rearranges landing pages every week, the site is small, and speed is acceptable, a cleanup by an Elementor developer costs far less than a migration. Converting old sections to containers and removing unused add-on packs often buys a lot. If the site is broken right now, the Elementor repair guide is the faster first stop.

The move makes sense when every new feature needs another add-on, when the license and update cycle eats real hours, or when leads depend on speed that Elementor's markup keeps taking back. The comparisons at Hello Elementor vs Next.js and Divi vs Elementor vs Next.js lay out the trade. Elementor is also common on top of other themes, so the Astra and OceanWP migration pages cover the same ground from their side. After the move, your team edits in Athena, and switching from WordPress shows what changes for them.

Questions people ask before they call

In a post meta field called _elementor_data, as JSON describing every container and widget with its settings. Elementor also saves a plain-text copy into the normal post content on each save, but that copy loses the structure. Templates, Theme Builder parts and popups are separate posts in the elementor_library post type.

Not with a one-click tool. The JSON has to be read, the content pulled out of each widget, and each layout matched to a page type with fields. Pages built from a few templates go quickly; hand-built pages need a person to decide what each block means. The cost guide covers how that affects price.

It can, if you want a faithful port. Global colors and fonts become design tokens, Theme Builder templates become layouts, and each page is checked against the original on a preview address. Many owners use the move to tidy the design, which is a Next.js rebuild rather than a straight migration.

Each form is rebuilt in Next.js with the same fields, notifications and integrations, plus server-side validation and spam protection. Past entries stay in WordPress, so export any you want to keep before launch. We test every form, every notification email and every CRM connection before the domain switches.

No. Extraction reads the stored JSON directly, which does not depend on a working Pro license. Pro features you use today, such as Theme Builder templates, popups and forms, are rebuilt in Next.js, so nothing needs to be renewed for the move. See Elementor Pro license problems if access is the issue.

Keep reading

Free · No obligation

Get your Elementor site counted and quoted

Send us the site. We will list every template, popup, form and add-on pack, tell you how much of the content extracts cleanly, and quote the move at a fixed price.

Which of these sounds like you? (pick any)

Rather talk now? Call (210) 346-0848.

CallGet a quote