How to Duplicate a Page in WordPress (or a Post)

I’m often asked by clients and readers of The Blog Mechanic if I know a quick and easy way to duplicate pages in WordPress.

Fortunately, I do. There are some simple plugins that you can use to clone a page or post in WordPress with just one click. And if for some reason you don’t want to use a plugin, there are a few other methods you can use instead.

In this article, I will show you how to duplicate a page in WordPress with and without a plugin, so you can choose the method that best suits you.

Why Clone Pages and Posts in WordPress

There are a few different scenarios where you might find yourself needing to quickly copy a page or a post in WordPress.

For example:

  • Sales Pages: you have created a sales page using a page builder and you want to reuse the page as a template for your next product.
  • Content Updates: you are updating a blog post and you don’t want to make edits to the published article until you’ve finished and finalized the content changes.
  • Blog Post Templates: you have the same or very similar text, links, and call to action at the bottom of blog posts.

Whatever your scenario is, you could manually copy and paste content from one page or post to another. But that’s time consuming and you run the risk of making an error when copying the content. It’s also not a viable solution for sales pages because you cannot copy and paste the layout and design of a page, you can only copy and paste the content.

Being able to automatically clone a page or post at the click of a button with all its settings, design, and layout, is a quicker and easier approach.

The Best Plugins to Easily Clone WordPress Pages and Posts

We’ll start with the duplicate page plugin first simply because this is the plugin that I use the most when cloning pages on my own website and on websites belonging to clients that I work with.

Note: for help installing and activating any of the listed plugins below, see my guide: how to install a WordPress plugn.

1. Duplicate Page Plugin

WordPress Duplicate Page Plugin

The Duplicate Page Plugin has been my go-to plugin for years. It’s easy to use and requires minimal configuration. You can clone pages, posts, and custom posts. But you cannot bulk clone pages and posts with this plugin, or comments associated with a post. To do that, the Yoast Duplicate Post plugin below is a better fit for your needs.

That said, if you’re just looking to clone a sales page or any other type of page that you’ve created with a page builder, or a blog post template, then this plugin is all you need to get the job done.

To get started, install and activate the Duplicate Page plugin. Once installed, go to Settings >> Duplicate Page

  • Choose the WordPress editor you are using
  • Leave all other settings as is
  • Click the save changes button
Duplicate Page Plugin Settings

Now, to clone a page or post, all you need to do is go to Posts >> All Posts. Hover your mouse over the post or page that you want to copy and click the Duplicate This link.

Clone post with the duplicate page plugin

Easy, right? Duplicate Page is a simple and lightweight plugin that won’t slow down your website with unnecessary features that you’ll likely never use. It makes cloning pages and posts easy and fast. But it does lack some useful features found in Yoast’s Duplicate Post plugin below.

2. Yoast Duplicate Post Plugin

With more than 3 million active installs, the Yoast Duplicate Post plugin is the most popular cloning plugin. At a basic level, you can copy a single page or post including associated comments, and you can bulk clone pages and posts too.

Then, to give you granular control, advanced settings let you choose exactly what parts of a page or post to clone, and which user roles are allowed to duplicate WordPress pages and posts on your website.

But what really makes this plugin shine is Yoast’s Rewrite & Publish feature that allows you to clone a post, make edits to the cloned post, and then automatically push your edits to the original article at the click of a button, without taking it offline. This makes content updates a streamlined process. Watch the video below to see how it works.

Pretty cool, huh? To get started, install and activate the Yoast Duplicate Post plugin.

Once activated, the default settings will work for most websites. However, there are a couple of settings you’ll likely need to change.

Go to Settings >> Duplicate Post

Yoast Duplicate Post Settings

The first tab is where you can choose what parts of a page or post to copy. By default, cloning comments associated with a post is not enabled. If you plan on using the Rewrite & Publish feature to update content, you’ll need to enable comments.

Next, if you have a multi author site or someone else other than yourself has access to the site, you need to go to the permissions tab.

Yoast Duplicate Post Permissions

By default, administrators and editors are allowed to duplicate pages in WordPress. You may want to change that to just admins.

When you’ve finished, don’t forget to click on the save changes button to apply your changes.

Now go to any page or post that you want to clone.

Clone a page or post

The ‘Clone’ link will create a duplicate copy of the page or post and save it as a draft without opening it in the WordPress editor.

Clicking the ‘New Draft’ link will make a copy of the page or post and open it in the editor so you can start working on it right away.

The ‘Rewrite & Publish’ link is best used to update content, not clone pages and posts as templates because once you’ve finished editing the cloned copy, all edits are automatically synced with the original page or post, and the duplicated version is deleted.

Next, I will show you how to duplicate pages and posts without a plugin.

How to Duplicate a Post in WordPress Without a Plugin

If you really don’t want to use a plugin, you can add some code to the function.php file of your WordPress theme.

But before I show you how to do that, make sure you backup your website and test this first on a staging site. Although adding the code is fairly easy and I am going to show you how to add it safely, adding custom PHP to a site can result in errors. See: How to Setup a WordPress Staging Site.

We are going to use a plugin called Code Snippets to add the code. The cool thing about this plugin is that if it detects any errors, it will automatically deactivate the code. This is the safest way to edit the functions.php file.

First, install and activate the Code Snippets plugin on your website. For more details, see my step by step guide on how to install WordPress plugins.

Upon activation, a new tab named ‘Snippets’ will be added to the left sidebar menu inside your WordPress admin area. Go to Snippets >> Add New

On the add new snippets page, enter a title and leave ‘Run Snippet Everywhere’ selected. Optionally, you can enter a description for the code in the description box.

Next, copy and paste the PHP code below into the code box.

/*
 * Function for post duplication. Dups appear as drafts. User is redirected to the edit screen
 */
function rd_duplicate_post_as_draft(){
	global $wpdb;
	if (! ( isset( $_GET['post']) || isset( $_POST['post'])  || ( isset($_REQUEST['action']) && 'rd_duplicate_post_as_draft' == $_REQUEST['action'] ) ) ) {
		wp_die('No post to duplicate has been supplied!');
	}
 
	/*
	 * Nonce verification
	 */
	if ( !isset( $_GET['duplicate_nonce'] ) || !wp_verify_nonce( $_GET['duplicate_nonce'], basename( __FILE__ ) ) )
		return;
 
	/*
	 * get the original post id
	 */
	$post_id = (isset($_GET['post']) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
	/*
	 * and all the original post data then
	 */
	$post = get_post( $post_id );
 
	/*
	 * if you don't want current user to be the new post author,
	 * then change next couple of lines to this: $new_post_author = $post->post_author;
	 */
	$current_user = wp_get_current_user();
	$new_post_author = $current_user->ID;
 
	/*
	 * if post data exists, create the post duplicate
	 */
	if (isset( $post ) && $post != null) {
 
		/*
		 * new post data array
		 */
		$args = array(
			'comment_status' => $post->comment_status,
			'ping_status'    => $post->ping_status,
			'post_author'    => $new_post_author,
			'post_content'   => $post->post_content,
			'post_excerpt'   => $post->post_excerpt,
			'post_name'      => $post->post_name,
			'post_parent'    => $post->post_parent,
			'post_password'  => $post->post_password,
			'post_status'    => 'draft',
			'post_title'     => $post->post_title,
			'post_type'      => $post->post_type,
			'to_ping'        => $post->to_ping,
			'menu_order'     => $post->menu_order
		);
 
		/*
		 * insert the post by wp_insert_post() function
		 */
		$new_post_id = wp_insert_post( $args );
 
		/*
		 * get all current post terms ad set them to the new post draft
		 */
		$taxonomies = get_object_taxonomies($post->post_type); // returns array of taxonomy names for post type, ex array("category", "post_tag");
		foreach ($taxonomies as $taxonomy) {
			$post_terms = wp_get_object_terms($post_id, $taxonomy, array('fields' => 'slugs'));
			wp_set_object_terms($new_post_id, $post_terms, $taxonomy, false);
		}
 
		/*
		 * duplicate all post meta just in two SQL queries
		 */
		$post_meta_infos = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id");
		if (count($post_meta_infos)!=0) {
			$sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
			foreach ($post_meta_infos as $meta_info) {
				$meta_key = $meta_info->meta_key;
				if( $meta_key == '_wp_old_slug' ) continue;
				$meta_value = addslashes($meta_info->meta_value);
				$sql_query_sel[]= "SELECT $new_post_id, '$meta_key', '$meta_value'";
			}
			$sql_query.= implode(" UNION ALL ", $sql_query_sel);
			$wpdb->query($sql_query);
		}
 
 
		/*
		 * finally, redirect to the edit post screen for the new draft
		 */
		wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_post_id ) );
		exit;
	} else {
		wp_die('Post creation failed, could not find original post: ' . $post_id);
	}
}
add_action( 'admin_action_rd_duplicate_post_as_draft', 'rd_duplicate_post_as_draft' );
 
/*
 * Add the duplicate link to action list for post_row_actions
 */
function rd_duplicate_post_link( $actions, $post ) {
	if (current_user_can('edit_posts')) {
		$actions['duplicate'] = '<a href="' . wp_nonce_url('admin.php?action=rd_duplicate_post_as_draft&post=' . $post->ID, basename(__FILE__), 'duplicate_nonce' ) . '" title="Duplicate this item" rel="permalink">Duplicate</a>';
	}
	return $actions;
}
 
add_filter( 'post_row_actions', 'rd_duplicate_post_link', 10, 2 );

Then, click on the ‘Save Changes and Activate’ button.

And finally, go to Posts >> All Posts to see that a duplicate link has been added.

duplicate link added to WordPress posts

You can now clone WordPress posts at the click of a button without using a plugin.

How to Duplicate a Page in WordPress Without a Plugin

To add a duplicate link to pages in WordPress, line 4, 101, and 108 of the code needs to be edited slightly. The process of adding the code is exactly the same. Repeat the steps above, but this time, give the new snippet a different name and add the code below.

/*
 * Function for post duplication. Dups appear as drafts. User is redirected to the edit screen
 */
function rd_duplicate_page_as_draft(){
	global $wpdb;
	if (! ( isset( $_GET['post']) || isset( $_POST['post'])  || ( isset($_REQUEST['action']) && 'rd_duplicate_post_as_draft' == $_REQUEST['action'] ) ) ) {
		wp_die('No post to duplicate has been supplied!');
	}
 
	/*
	 * Nonce verification
	 */
	if ( !isset( $_GET['duplicate_nonce'] ) || !wp_verify_nonce( $_GET['duplicate_nonce'], basename( __FILE__ ) ) )
		return;
 
	/*
	 * get the original post id
	 */
	$post_id = (isset($_GET['post']) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
	/*
	 * and all the original post data then
	 */
	$post = get_post( $post_id );
 
	/*
	 * if you don't want current user to be the new post author,
	 * then change next couple of lines to this: $new_post_author = $post->post_author;
	 */
	$current_user = wp_get_current_user();
	$new_post_author = $current_user->ID;
 
	/*
	 * if post data exists, create the post duplicate
	 */
	if (isset( $post ) && $post != null) {
 
		/*
		 * new post data array
		 */
		$args = array(
			'comment_status' => $post->comment_status,
			'ping_status'    => $post->ping_status,
			'post_author'    => $new_post_author,
			'post_content'   => $post->post_content,
			'post_excerpt'   => $post->post_excerpt,
			'post_name'      => $post->post_name,
			'post_parent'    => $post->post_parent,
			'post_password'  => $post->post_password,
			'post_status'    => 'draft',
			'post_title'     => $post->post_title,
			'post_type'      => $post->post_type,
			'to_ping'        => $post->to_ping,
			'menu_order'     => $post->menu_order
		);
 
		/*
		 * insert the post by wp_insert_post() function
		 */
		$new_post_id = wp_insert_post( $args );
 
		/*
		 * get all current post terms ad set them to the new post draft
		 */
		$taxonomies = get_object_taxonomies($post->post_type); // returns array of taxonomy names for post type, ex array("category", "post_tag");
		foreach ($taxonomies as $taxonomy) {
			$post_terms = wp_get_object_terms($post_id, $taxonomy, array('fields' => 'slugs'));
			wp_set_object_terms($new_post_id, $post_terms, $taxonomy, false);
		}
 
		/*
		 * duplicate all post meta just in two SQL queries
		 */
		$post_meta_infos = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id");
		if (count($post_meta_infos)!=0) {
			$sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
			foreach ($post_meta_infos as $meta_info) {
				$meta_key = $meta_info->meta_key;
				if( $meta_key == '_wp_old_slug' ) continue;
				$meta_value = addslashes($meta_info->meta_value);
				$sql_query_sel[]= "SELECT $new_post_id, '$meta_key', '$meta_value'";
			}
			$sql_query.= implode(" UNION ALL ", $sql_query_sel);
			$wpdb->query($sql_query);
		}
 
 
		/*
		 * finally, redirect to the edit post screen for the new draft
		 */
		wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_post_id ) );
		exit;
	} else {
		wp_die('Post creation failed, could not find original post: ' . $post_id);
	}
}
add_action( 'admin_action_rd_duplicate_post_as_draft', 'rd_duplicate_post_as_draft' );
 
/*
 * Add the duplicate link to action list for post_row_actions
 */
function rd_duplicate_page_link( $actions, $post ) {
	if (current_user_can('edit_posts')) {
		$actions['duplicate'] = '<a href="' . wp_nonce_url('admin.php?action=rd_duplicate_post_as_draft&post=' . $post->ID, basename(__FILE__), 'duplicate_nonce' ) . '" title="Duplicate this item" rel="permalink">Duplicate</a>';
	}
	return $actions;
}

add_filter( 'page_row_actions', 'rd_duplicate_post_link', 10, 2 );

Now, when you go to Pages >> All Pages and hover over any page title on your site, you will see a duplicate link.

A Simple Shortcut to Manually Duplicate WordPress Pages and Posts

If you don’t want to use a plugin or edit your functions.php file, then the only other option you have is to manually copy and paste content from one URL to another. The problem with this approach is that sometimes the HTML formatting (heading tags, paragraph tags, bullets, etc) of content can be lost when copying it over. And you run the risk of making an error.

To ensure that doesn’t happen, and to make the process of copying and pasting a little faster, I have a simple shortcut to share with you, but it only works with the Gutenberg WordPress editor.

To get started, open any post or page in the editor. Switch to the Post tab in the right sidebar to make sure no individual blocks are selected. If individual blocks are selected, only the content of those blocks will be copied.

Now, in the top right corner of the screen, click the three dots to open up the options and select ‘Copy all Content‘ under the tools section at the bottom of the menu. Then close the page.

Now, with the content copied to your clipboard, create a new page or post. Click anywhere in the post editor underneath the title area. To paste the content hold down Command + V on a Mac or Control + C on a PC.

Summary

I hope this article has helped you learn how to duplicate a page in WordPress, and easily clone posts. To quickly recap:

The easiest, quickest, and most recommended way to clone WordPress pages and posts is with a plugin. I recommend Yoast Duplicate Post or Duplicate Page.

You can also copy pages and posts without a plugin by adding the provided custom PHP code to the functions.php file of your active WordPress theme. The code will add a duplicate link to both pages and posts.

And finally, if you’re using the WordPress Gutenberg editor and you just need to copy the body content of a page or post – not all the settings, featured image, design, and layout – you can use Gutenberg’s built-in copy all content feature.

If you liked this article, you might also enjoy my guide on how to change the author in WordPress and how to speed up a slow website.

Leave a Comment