How to Copy a Page from One WordPress Site to Another

In this tutorial, I’d like to cover two ways of how you can copy a WordPress page from one site to another.

I’m not going to talk about the export-and-import approach here, because, first of all, you can not run it just for some specific pages, so it is not really convenient to perform the export of all the content every time you need to sync some tiny changes made in a WordPress page to another site.

And of course, everything in this tutorial applies not only to simple WordPress pages but also:

  • pages packed with custom fields (ACF, Carbon Fields, Simple Fields, etc),
  • pages created with page builders (Elementor, Divi, WPBakery, Beaver Builder, etc),
  • pages, created with either the classic or block editor.

So let’s get started now.

Method 1. Using a Plugin (Recommended)

In the first method, I want to describe how you can do it with my plugin, because it is the easiest, almost one-click method. Much easier than doing everything programmatically (we will talk about it later in this tutorial).

All right, so to copy pages from one WordPress site to another using this method, you need to do three simple steps:

  1. Install and activate the Simple WP Crossposting plugin.
  2. Add a target site in plugin settings (and optionally configure the settings for your needs).
  3. Then, simply copy a WordPress page to another site when editing it. You just need to select which of the added sites you want to copy it to using checkboxes (or, if you activate the “Auto-Mode” in the plugin settings, it will be automatically copied to all added sites).

The example is in the screenshot below:

Example of how to copy a page from one WordPress site to another
Just select a WordPress website you would like to copy a page to in the “Publish on” section and hit the “Publish” or “Save” button. Here, I’m using the block editor, by the way, but the classic editor is fully supported as well.

You can also copy one or multiple pages from the “All Pages” admin screen, using the bulk actions:

Copy pages from one WordPress site to another
Example of how you can copy a WordPress page to another site without going into “Edit”.

Learn more about my Simple WP Crossposting plugin.

That’s all for the simple plugin approach, guys, only three simple steps as promised, and right now we’re going to dive deep into the programmatic way, in case you’re uncomfortable with using third-party plugins on your website.

Method 2. Programmatically, with the WordPress REST API

It is also possible to copy pages from one WordPress site to another without using any plugins. But unless your pages are a part of the same multisite network, the only way to do it is with the WordPress REST API.

Below is a step-by-step guide on how to do it.

Decide on custom fields and register all of them on the second website

Most likely, your page isn’t only the title and the content, and it has some custom fields. Even when you’re working with Elementor, it has all the data stored as a JSON string in literally one custom field (it is _elementor_data, by the way).

The main point here is that if you just provide all the custom fields in your REST API request, then nothing will happen, and the page copy isn’t going to have the same custom fields as the original one, so we need to register every custom field on the second website with the help of the register_meta() function.

Example:

register_meta(
	'post', 
	'custom_field_key', 
	array(
		'type' => 'string',
		'show_in_rest' => true,
	)
);

You need to do it for every custom field; more examples can be found in this tutorial. One more thing, the register_meta() function should be used inside the rest_api_init action hook.

Create a PHP function which will copy a WordPress page from one site to another

Below is the complete function, but the question is – where should we run it in our website code? And there are different options:

  • First of all, you can, of course, copy the pages to another website automatically every time you hit the “Publish” button. The action hook save_post_page will help you with that.
  • You can create a bulk action and connect this function to it.
  • Another option is like in the screenshot above, you can display the checkboxes in the block editor sidebar, and only copy a page to another website when an appropriate checkbox is checked.

And here is the function code:

/*
 * Allows you to copy WordPress page to another site
 * @author Misha Rudrastyh
 */
function rudr_copy_wordpress_page_to_other_site( $page_id ) {
	
	// we need this data to connect to REST API
	$login = '';
	$pwd = '';
	$url = ''; // URL of our target site
	
	// let's get page data
	$page = get_post( $page_id );	
	// the array with the page data for the REST API request
	$page_data = array(
		'title' => $page->post_title,
		'status' => $page->post_status,
		'date' => $page->post_date,
		'slug' => $page->post_name,
		'menu_order' => (int) $page->menu_order,
		// here we copy content from one WordPress site to another
		'content' => $page->post_content,
		// 'parent' => $page->post_parent,
		// 'featured_media' => get_post_thumbnail_id( $page->ID ),
		'meta' => array(),
		'password' => $page->post_password,
		'template' => get_page_template_slug( $page ),
		'comment_status' => $page->comment_status,
		'ping_status' => $page->ping_status,
	);
	
	// it is time to add meta fields into the request
	$page_meta = get_post_meta( $page_id );
	foreach( $post_meta as $meta_key => $meta_values ) {
		// don't forget about multiple meta values for the same key
		// we're just using a simplified version here
		$meta_value = reset( $meta_values );
	
		// sometimes we need to do extra stuff here like maybe_unserialize()
		// if you don't want to worry about it, check my plugin ;)
		
		// add to the REST API request body
		$page_data[ 'meta' ][ $meta_key ] = $meta_value;

	}
	
	$response = wp_remote_post(
		"{$url}/wp-json/wp/v2/pages",
		array(
			'headers' => array(
				'Authorization' => 'Basic ' . base64_encode( "{$login}:{$pwd}" ),
				'Content-Type' => 'application/json; charset=utf-8',
			),
			'body' => json_encode( $page_data )
		)
	);
	
	if( 'Created' === wp_remote_retrieve_response_message( $response ) ) { 
		// Everything is great!
		return true;	
		// You can also return an ID of a newly created page this way:
		// $response_body = json_decode( wp_remote_retrieve_body( $response ) );
		// return $response_body->id;
	} else {
		return false;	
	}
	
}

Some comments for this code:

  • First things first, if you don’t know where to get $login and $pwd values, read about application passwords.
  • Also, you can see that I’ve commented parent parameter, why? Because the parent page ID on “Site 1” and on “Site 2” is going to be different. Most likely, we will need to send one more REST API request to get a parent page ID by slug.
  • For the same reason, I commented the featured_media parameter. If we pass a featured image ID there, most likely, we will either get a REST API error, or a wrong image will be assigned to the page. If you want to dive deep into this topic, you can read my other post about uploading media with the REST API, or you can simply use my plugin, which will handle it for you.
  • In the same way, we can copy posts if we change the REST API endpoint from /wp/v2/pages to /wp/v2/posts. What about custom post types? It depends on the rest_base parameter you used when registering it, /wp/v2/{$rest_base} or if you didn’t provide it, then it is just a custom post type name.
  • If you want to move a page (i.e., to remove the original version of content), then just add the wp_delete_post() function at the end of the main PHP function.

If you have any questions about the plugin or about the code snippet above, please feel free to ask them in the comments section below.

Misha Rudrastyh

Misha Rudrastyh

Hey guys and welcome to my website. For more than 15 years I've been doing my best to share with you some superb WordPress guides and tips for free.

Need some developer help? Contact me

Follow me on X