Move WordPress Content Without Losing Authors or Dates

Moving WordPress posts between sites takes more than copying titles and body text. Each post also has an author, publication dates, categories, images, and links to other records. Those details can change or disappear even when the import reports success. In a recent migration workflow, I had to check each of them separately. The most useful checks were simple: match people by a reliable identity, preserve the original dates, and make reruns update the same records. Here is how I approached those checks and made exceptions visible to the editor reviewing the transfer.
Match authors across the two sites
The source system could safely export internal IDs, but those IDs meant nothing on the destination. Staff member 418 on one site might be a page, an attachment, or no record at all on another. I had to export stable human-facing identity alongside internal references, then resolve it under strict rules during import.
I used exact, published staff identity as the safe path and treated ambiguity as a warning instead of guessing. That feels conservative until you imagine attaching a clinical article to the wrong reviewer. A migration that quietly invents certainty is more dangerous than one that asks for review.
Preserve publication and draft dates
Published content needs its original publication and modified timestamps. Drafts also need the date editors expect to see when they resume work. Normalizing every row to the import time would have made the destination look fresh while erasing history.
The importer now validates each incoming date, preserves draft dates deliberately, and rejects impossible values without discarding the rest of the report. These checks prevent the transfer from replacing the original editorial history with the date the import ran.
Make interrupted imports safe to retry
A browser request can time out after the server has already created a post. Retrying a blank-ID row can then create a duplicate. I added duplicate protection based on the stable source fields available to the importer and made failures visible per row. The operator can see what was created, updated, skipped, warned, or failed.
The useful rule is simple: never let an HTTP response be the only proof that a write happened. Imports need durable identifiers, idempotent behavior, and a report that survives the request that started them.
Keep migration settings separate. I did not change the default export into a special-purpose format. I added an explicit migration profile. The normal same-site workflow kept its existing behavior, while the migration profile included authorship, original dates, taxonomies, and the custom fields required by the destination theme.
Keeping those settings separate makes maintenance easier. A specialized workflow should announce its assumptions instead of silently changing the format used by existing operators and older releases.
Check relationships before importing
- List every relationship whose numeric ID changes between sites.
- Choose a stable identity and define what counts as ambiguous.
- Write date rules separately for drafts and published content.
- Make every write safe to retry after a timeout.
- Report warnings separately from hard failures.
- Test the untouched client file, not only a clean fixture.
I also keep the source values during the observation window. Destructive cleanup can wait until the destination has been reviewed and the reconciliation report is quiet.
Compare the imported content with the source
Migration budgets often focus on volume: how many posts, how many images, how long the transfer takes. The risk I now surface first is meaning. Incorrect authorship can undermine trust. Changed dates can affect compliance and search behavior. Missing relationships can make a page factually incomplete even when it renders without errors.
That is why I test representative content types, edge cases, and reruns before I call a migration ready. The destination should preserve the source information, with an explanation for every exception.
How I qualified the real file. Clean fixtures proved the parser, but the untouched export proved the workflow. I previewed the complete file without writes, checked its row and column counts, and inspected values known to be awkward: blank destination IDs, repeated names, remote images, escaped schema fragments, and relationships that could not resolve on the target. I then used disposable local records for a bounded real import and cleaned them up after comparing the report with WordPress state.
This distinction is important. A fixture tells me whether the behavior I imagined works. An actual export can expose values and relationships that a small test fixture did not cover. I keep both in the test strategy and never “repair” the source file privately just to help the importer pass.
Agree on the migration rules before starting
Before moving content, write down how authors, dates, images, and related records should be handled. Have an editor review those rules alongside a developer. Then test a small set of real posts, including incomplete and ambiguous records, and run the import twice. The destination should preserve the source information, and the second run should avoid duplicates. Keep the source export and the exception report until the editor has checked the results.
Photo by RDNE Stock project on Pexels.
Written by
Adrian Saycon
A developer with a passion for emerging technologies, Adrian Saycon focuses on transforming the latest tech trends into great, functional products.



