
Learn how to duplicate a post in WordPress. In this tutorial, we’ll show you a clean, easy way to duplicate posts 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.
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.
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 tooThis 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.

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.
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 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:

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.
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.
Now, let’s walk through duplicating your post content using Gutenberg’s built-in features:

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.
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.
Now, let’s set up post duplication using a dedicated plugin:

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.

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.
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.





