There are various scenarios in which you need to create a new page from another page. By default, WordPress does not have the ability to duplicate pages or posts, Fortunately, duplicating pages and posts and all their associated data in WordPress can be easy. 
In this article, we’ll look at how to clone a page or post with two methods.

How to duplicate a page in WordPress without plugin

In the first method, we manually copy the content of the page or posts and paste it on the new page.
In the second method, we add a duplicate button to all pages and posts using a snippet of code that is placed in the “functions.php” file. If you have a habit of duplicating pages, we recommend this method.

Method 1.Duplicate a page in WordPress manually

  • Click on Posts or Pages in your dashboard.
  • Click the ellipses menu (the three vertical dots) to the right of the post or page you want to copy.
  • Select “Copy all content“.
Copy all content in WordPress pages
  • Click on New Post or New Page.
  • In the new post or page, paste the clipboard content.
paste content the new WordPress page

The new page or post should now be a clone of the old one.

Method 2.Duplicate page using a snippet of code

To enable duplicating for posts and pages, you’ll need to access your functions.php file and open it for editing. Then you’ll need to add the following code snippet to the end of the file:

You must create a child theme before making any changes to functions.php file. Otherwise, the applied changes will be lost after each update.
Create child theme in WordPress step by step [without plugin]

As an alternative method, you can use the Code Snippets plugin to insert your codes into WordPress.

add_filter( 'post_row_actions', 'rd_duplicate_post_link', 10, 2 );
add_filter( 'page_row_actions', 'rd_duplicate_post_link', 10, 2 );
function rd_duplicate_post_link( $actions, $post ) {

	if( ! current_user_can( 'edit_posts' ) ) {
		return $actions;

	$url = wp_nonce_url(
				'action' => 'rd_duplicate_post_as_draft',
				'post' => $post->ID,

	$actions[ 'duplicate' ] = '<a href="' . $url . '" title="Duplicate this item" rel="permalink">Duplicate</a>';

	return $actions;

add_action( 'admin_action_rd_duplicate_post_as_draft', 'rd_duplicate_post_as_draft' );

function rd_duplicate_post_as_draft(){

	// check if post ID has been provided and action
	if ( empty( $_GET[ 'post' ] ) ) {
		wp_die( 'No post to duplicate has been provided!' );

	// Nonce verification
	if ( ! isset( $_GET[ 'duplicate_nonce' ] ) || ! wp_verify_nonce( $_GET[ 'duplicate_nonce' ], basename( __FILE__ ) ) ) {

	// Get the original post id
	$post_id = absint( $_GET[ '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 (I am sure it is, but just in a case), create the post duplicate
	if ( $post ) {

		// 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
		$new_post_id = wp_insert_post( $args );
		$taxonomies = get_object_taxonomies( get_post_type( $post ) ); // returns array of taxonomy names for post type, ex array("category", "post_tag");
		if( $taxonomies ) {
			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
		$post_meta = get_post_meta( $post_id );
		if( $post_meta ) {

			foreach ( $post_meta as $meta_key => $meta_values ) {

				if( '_wp_old_slug' == $meta_key ) { // do nothing for this meta key

				foreach ( $meta_values as $meta_value ) {
					add_post_meta( $new_post_id, $meta_key, $meta_value );

		// finally, redirect to the edit post screen for the new draft
		// wp_safe_redirect(
		// 	add_query_arg(
		// 		array(
		// 			'action' => 'edit',
		// 			'post' => $new_post_id
		// 		),
		// 		admin_url( 'post.php' )
		// 	)
		// );
		// exit;
		// or we can redirect to all posts with a message
					'post_type' => ( 'post' !== get_post_type( $post ) ? get_post_type( $post ) : false ),
					'saved' => 'post_duplication_created' // just a custom slug here
				admin_url( 'edit.php' )

	} else {
		wp_die( 'Post creation failed, could not find original post.' );


add_action( 'admin_notices', 'rudr_duplication_admin_notice' );

function rudr_duplication_admin_notice() {

	// Get the current screen
	$screen = get_current_screen();

	if ( 'edit' !== $screen->base ) {

    //Checks if settings updated
    if ( isset( $_GET[ 'saved' ] ) && 'post_duplication_created' == $_GET[ 'saved' ] ) {

		 echo '<div class="notice notice-success is-dismissible"><p>Post copy created.</p></div>';

Code credit:

Update the file. After that, a Duplicate button should now appear when you hover over a page or post you want to clone.

duplicate page in WordPress

If this article is difficult for you to read in text, you can watch the video version below.

That’s it, If you have a question, be sure to comment for us to answer.

Share this post

Hi, my name is Maya and I’m a WordPress plugin developer. I created this website to share some of the helpful codes that I’ve used in my own projects.
If you’re looking for a custom plugin for your website, you can contact me by clicking on Hire a developer in the menu. I’d love to hear from you.

Articles: 53

Leave a Reply

Your email address will not be published. Required fields are marked *