How to Duplicate a Post in WordPress

Learn how to duplicate a post in WordPress. In this tutorial, we’ll show you a clean, easy way to duplicate posts using WPCodeBox.

Meet WPCodeBox: The Best Code Snippets Plugin for WordPress
faces
Join thousands of developers and agencies who are working better and faster using WPCodeBox

You often need to reuse layouts, content, or elements from existing posts. Manual copying wastes time and increases the chance of errors.

Many WordPress plugins offer duplication features, but they add unnecessary bloat to your site. Multiple plugin stacks also make your WordPress site slower and harder to maintain.

In this article, I’ll share how to duplicate a post in WordPress without bloating your site.

Why Duplicate a WordPress Post?

Duplicating successful post layouts saves you hours of work. You preserve your exact formatting, categories, and layouts without rebuilding from scratch. This works perfectly for weekly series, monthly reports, and seasonal content that need identical structures. Duplicating templates lets you focus on creating content rather than formatting.

Post copies also help you with testing and A/B experimentation. You can create duplicate versions and safely test different headlines, images, or content variations. Your original content stays untouched while you experiment with improvements.

Updating older posts becomes safer when you work on draft copies. You can duplicate a published post and make changes at your own pace. This prevents unfinished versions from going live while you improve your content.

Method 1: Duplicate a Post Without a Plugin (Recommended)

Adding a simple “Duplicate” button to your post list doesn’t necessarily require installing a plugin. You can do this with a simple snippet that’s not only lightweight but also keeps your site running without unnecessary bloat.

Here’s the code snippet that you can copy to your WordPress site:

<?php

/*
 * Function for post duplication. Dups appear as drafts. User is redirected to the edit screen
 */
function rd_duplicate_post_as_draft()
{
    if (!current_user_can("edit_posts")) {
        return;
    }
    
    /*
     * Nonce verification
     */
    if (
        !isset($_GET["duplicate_nonce"]) ||
        !wp_verify_nonce($_GET["duplicate_nonce"], basename(__FILE__))
    ) {
        return;
    }
    
    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!");
    }



    /*
     * 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 = [
            "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, [
                "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_safe_redirect( wp_get_referer() ); // Option to not get redirected to new post edit page, but stay where one was.
        // wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_post_id ) ); // replace this line with the following
        wp_safe_redirect(
            admin_url("post.php?action=edit&post=" . $new_post_id)
        ); // Security related edit: @link https://developer.wordpress.org/reference/functions/wp_safe_redirect/
        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);
add_filter("page_row_actions", "rd_duplicate_post_link", 10, 2); // add the link to pages too

This snippet adds a Duplicate button under every post in your WordPress admin. Clicking the link creates an exact copy with the same content, formatting, categories, and metadata. The copy saves as a draft so you can edit it immediately.

duplicate button in post list

The snippet is highly customizable and allows you to change the duplicate status from “draft” to “publish” by modifying the post_status value. You can remove the page filter if you only want to add duplication for posts. The snippet will automatically assign you as the author of the new copy.

Step-by-Step Guide to Adding the Duplicate Button Snippet Using WPCodeBox

Adding the code directly to your theme’s functions.php file risks breaking your site. A single typo can trigger white screens or fatal errors that take your site offline. Theme updates also wipe out your custom code, forcing you to recreate everything.

WPCodeBox solves these problems by giving you a safe, controlled environment for managing all your WordPress code. It provides an intelligent code editor that protects your site from broken code. It detects most syntax errors and automatically disables problematic snippets before they cause issues. You also get WordPress autocomplete, documentation on hover, and smart code suggestions that help you write faster.

wpcodebox snippet plugin

WPCodeBox even comes with cloud functionality that allows you to save snippets to the cloud and sync them across multiple WordPress sites in just seconds. It also lets you turn snippets into standalone plugins, which makes handing off projects to clients much simpler. Plus, the condition builder lets you control exactly where and when each snippet executes.

Now, let’s walk through adding this snippet to your site step by step:

  1. Install and activate WPCodeBox on your WordPress site through the plugins menu.
  2. Navigate to WPCodeBox 2 and click the “Add New Snippet” button to create a new snippet.
  3. Enter a descriptive name for your snippet, such as “Duplicate Post Button,” which helps you identify it later.
  4. Copy the entire code block and paste it into the code editor area.
  5. Set the following from the configuration panel:
    • Type: PHP Snippet
    • How to run the snippet: Always (On Page Load)
    • Where to insert the snippet: Plugins Loaded (Default)
  6. Click the Save button to store your snippet in a safe, disabled state to prevent any accidental errors.
  7. Toggle the snippet to “Enabled” to add a duplicate button to every post in your WordPress admin.
duplicate button snippet

After enabling the snippet, visit your Posts > All Posts page, and you’ll see a new “Duplicate” button appear under each post title next to Quick Edit and Trash.

You can now duplicate any post or page with a single click. The duplicate post opens as a draft in the editor, and you can make modifications as you like.

Method 2: Duplicate Using the Gutenberg Editor (Manual)

Gutenberg includes built-in tools that let you duplicate post content without any code or plugins. This manual approach works well when you need a quick copy of your article structure and blocks. It’s perfect for simple content duplication where metadata doesn’t matter as much.

Step-by-Step Guide to Duplicating Content in Gutenberg

Now, let’s walk through duplicating your post content using Gutenberg’s built-in features:

  1. Open the post you want to duplicate in the Gutenberg editor.
  2. Click the three-dot menu icon in the top-right corner of the editor.
  3. Click Copy all content from the dropdown menu.
gutenberg copy all content option
  1. Navigate back to Posts > Add New to create a blank post.
  2. Click inside the empty editor and paste your copied content using Ctrl+V (or Cmd+V on Mac).
  3. The entire post structure, blocks, and formatting appear in your new editor.
  4. Add your post title manually since it doesn’t copy with the content.

This method only duplicates the content within the editor area. You’ll need to manually set categories, tags, featured images, and SEO details for the new post. Custom fields, page templates, and metadata also transfer separately.

The manual Gutenberg method works for simple duplications but requires extra steps for complete post copies. The code snippet method handles everything automatically, including categories, images, and metadata.

Method 3: Duplicate a Post Using a Plugin

Dedicated WordPress plugins provide another way to duplicate posts on your site. This method works similar to the code snippet we shared earlier, but you need to maintain an additional plugin instead. The plugin adds overhead to your WordPress installation and increases the potential for conflicts with other plugins.

Step-by-Step Guide to Using a Duplication Plugin

Now, let’s set up post duplication using a dedicated plugin:

  1. Go to Plugins > Add New in your WordPress dashboard.
  2. Search for Yoast Duplicate Post in the plugin repository.
  3. Install and activate the plugin, and then navigate to Posts > All Posts to view your post list.
  4. Hover over any post and click the Clone button.
yoast duplicate post

The plugin also adds a New Draft link that opens the duplicate in the editor for immediate editing. You can find additional copy options on the post edit screen and in the admin bar for quick access.

yoast duplicate post draft button

As this method installs a new plugin on your WordPress site, it adds database queries, code, and potential conflicts to your installation. You also need to keep the plugin updated for security and compatibility.

The code snippet method provides the same functionality without adding another plugin, uses minimal resources, and doesn’t require ongoing maintenance or updates.

More on Duplicating Posts in WordPress

What is the difference between duplicate and clone in WordPress?

Duplicate and clone work exactly the same in WordPress. Both terms create an identical copy of your post or page with all the original content. Plugins just use different names for the same action.

How to duplicate a WordPress page without a plugin?

You can duplicate pages by adding a simple code snippet to your WordPress site. The snippet creates a Duplicate button under each page in your list. When you click this button, WordPress copies your page as a draft for editing. The duplicate preserves your content, formatting, and structure while keeping the original page untouched.

What is the plugin for duplicate pages in WordPress?

Yoast Duplicate Post is a popular plugin that works well for duplicating pages on your WordPress site. The plugin adds clone and draft options directly to your page list for easy access. It also supports bulk actions so you can copy multiple pages at once. However, a code snippet gives you the same result without adding another plugin to keep your site lightweight.

More Ways to Customize Your WordPress Website

Related Tutorials

WPCodeBox is a WordPress Code Snippets Manager that allows you to share your WordPress Code Snippets across your sites.