How PostDeploy keeps WPML translations linked after a push
Push a WPML-translated page to another site, and the content itself usually arrives fine — the design, the text, the images. What doesn't automatically come with it is the one thing WPML needs to treat it as a translation at all: the link back to its siblings in other languages. Without that link, the page just sits there as an ordinary, disconnected post. The language switcher won't find it. WPML has no idea it's related to anything.
Why a translation is a separate post to begin with
WPML doesn't store one post with several language variants inside it. Your English page and its French translation are two completely separate posts, each with its own post ID, each editable independently in its own right. What makes WPML treat them as translations of each other is a second piece of bookkeeping: a translation group ID (WPML calls it a trid) that both posts share, stored separately from the posts themselves.
That grouping is exactly the kind of thing discussed in the last post about why migrations break in general — it's an internal identifier, correct only within the database that assigned it. Push the French post to another site, and that site's WPML has never heard of the trid the source site used for it. The post arrives; the group membership doesn't.
What actually has to happen
After the translated post is imported, something has to explicitly tell the destination's WPML: "this new post belongs in the same translation group as the other language(s) already here, if any." That's a distinct step from importing the post's content — it has to run after the import, once the new post actually exists and has an ID of its own to register.
It also has to handle both directions correctly: pushing the first language of a group to a brand-new site (nothing to link to yet, the group starts here) and pushing a second or third language later, once earlier ones are already there (link into the existing group, don't start a new one).
The part that's easy to get subtly wrong
A translation group's trid is just a number WPML assigned on the source site — and numbers collide. A large site accumulates thousands of posts and translation groups over time, and there's nothing stopping a translation group's trid from coincidentally matching a real post ID elsewhere in the same export pipeline. If the code tracking "which destination post does this source object map to" uses the same lookup table for both post IDs and trids without distinguishing the two, that coincidence corrupts a mapping — the wrong post's stored destination ID gets overwritten with someone else's.
This is a real, specific failure mode, not a hypothetical one — it's the kind of bug that only shows up on a site with enough content for an ID collision to actually happen, and it produces exactly the symptom you'd least expect from a "translation linking" problem: a page showing a sibling translation's content instead of its own, on a push that otherwise completed without any visible error.
What PostDeploy does about all of this
Pushing a WPML-translated post — one language, or every language in the group at once — links each imported post into the correct translation group on the destination automatically, as its own step after the content import. Mapping a source object to its destination copy is kept unambiguous regardless of what a translation group's internal ID happens to number-match, so a large site's real post/trid overlap can't corrupt an unrelated mapping. The Dashboard's language picker shows which languages exist for a post and pushes the ones you pick — one at a time, or all of them — and "Push Selected Languages" reports each language's own result individually, so a conflict or a destination-side hiccup on one language doesn't block the rest.
Try it
PostDeploy Free moves Posts, Pages, and custom post types as plain content. PostDeploy Pro adds the WPML translation-group linking described here, along with ACF and Elementor reference resolution.