{"id":292190,"date":"2026-04-20T06:22:03","date_gmt":"2026-04-20T06:22:03","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/classic-menu-duplicator\/"},"modified":"2026-04-20T06:29:54","modified_gmt":"2026-04-20T06:29:54","slug":"swift-menu-duplicator","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/swift-menu-duplicator\/","author":20002658,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.1","stable_tag":"1.0.1","tested":"7.0","requires":"6.0","requires_php":"7.4","requires_plugins":null,"header_name":"Swift Menu Duplicator","header_author":"Al Amin Ahamed","header_description":"Duplicate menus and items, snapshot revisions, export\/import JSON, manage all menus in bulk, copy across multisite, automate with WP-CLI, and integrate via REST API.","assets_banners_color":"172134","last_updated":"2026-04-20 06:29:54","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/mralaminahamed\/swift-menu-duplicator","header_author_uri":"https:\/\/github.com\/mralaminahamed","rating":0,"author_block_rating":0,"active_installs":0,"downloads":104,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"mralaminahamed","date":"2026-04-20 06:28:19"},"1.0.1":{"tag":"1.0.1","author":"mralaminahamed","date":"2026-04-20 06:29:54"}},"upgrade_notice":{"1.0.1":"<p>WP-CLI users: the command has been renamed from <code>wp menu-duplicator<\/code> to <code>wp swift-menu-duplicator<\/code>. Update any scripts or aliases accordingly.<\/p>","1.0.0":"<p>Initial release \u2014 no upgrade steps required.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3510625,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3510625,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3510625,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3510625,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0","1.0.1"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3510503,"resolution":"1","location":"assets","locale":"","width":1280,"height":800},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3510503,"resolution":"2","location":"assets","locale":"","width":1280,"height":800},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3510503,"resolution":"3","location":"assets","locale":"","width":1280,"height":800},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3510503,"resolution":"4","location":"assets","locale":"","width":1280,"height":800},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3510503,"resolution":"5","location":"assets","locale":"","width":1280,"height":800}},"screenshots":{"1":"Duplicate Menu button in the menu editor footer.","2":"Menu Manager page \u2014 sortable list of all menus with bulk actions.","3":"Snapshot panel in the menu editor \u2014 browse, restore, and delete revisions.","4":"JSON import form with URL find &amp; replace and dry-run preview.","5":"WP-CLI <code>duplicate<\/code> and <code>export<\/code> commands in a terminal."},"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[2738,9055,42018,231,1753],"plugin_category":[43],"plugin_contributors":[221130],"plugin_business_model":[],"class_list":["post-292190","plugin","type-plugin","status-publish","hentry","plugin_tags-copy","plugin_tags-duplicate","plugin_tags-menu-manager","plugin_tags-menus","plugin_tags-navigation","plugin_category-customization","plugin_contributors-mralaminahamed","plugin_committers-mralaminahamed"],"banners":{"banner":"https:\/\/ps.w.org\/swift-menu-duplicator\/assets\/banner-772x250.png?rev=3510625","banner_2x":"https:\/\/ps.w.org\/swift-menu-duplicator\/assets\/banner-1544x500.png?rev=3510625","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/swift-menu-duplicator\/assets\/icon-128x128.png?rev=3510625","icon_2x":"https:\/\/ps.w.org\/swift-menu-duplicator\/assets\/icon-256x256.png?rev=3510625","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/swift-menu-duplicator\/assets\/screenshot-1.png?rev=3510503","caption":"Duplicate Menu button in the menu editor footer."},{"src":"https:\/\/ps.w.org\/swift-menu-duplicator\/assets\/screenshot-2.png?rev=3510503","caption":"Menu Manager page \u2014 sortable list of all menus with bulk actions."},{"src":"https:\/\/ps.w.org\/swift-menu-duplicator\/assets\/screenshot-3.png?rev=3510503","caption":"Snapshot panel in the menu editor \u2014 browse, restore, and delete revisions."},{"src":"https:\/\/ps.w.org\/swift-menu-duplicator\/assets\/screenshot-4.png?rev=3510503","caption":"JSON import form with URL find &amp; replace and dry-run preview."},{"src":"https:\/\/ps.w.org\/swift-menu-duplicator\/assets\/screenshot-5.png?rev=3510503","caption":"WP-CLI <code>duplicate<\/code> and <code>export<\/code> commands in a terminal."}],"raw_content":"<!--section=description-->\n<p><strong>Swift Menu Duplicator<\/strong> gives you full control over your WordPress navigation menus. Clone any menu in one click, manage all menus from a dedicated admin page, version them with snapshots, move them across Multisite sub-sites, and automate everything from the command line or REST API.<\/p>\n\n<h3>One-Click Duplication<\/h3>\n\n<ul>\n<li>Duplicate button right in the menu editor footer \u2014 no page reload required<\/li>\n<li>Full hierarchy preserved via a two-pass clone that remaps all parent-child item IDs<\/li>\n<li>All item metadata copied \u2014 type, object, URL, target, CSS classes, XFN, description<\/li>\n<li>Duplicate individual menu items directly from the menu editor<\/li>\n<li>Custom name support \u2014 filter <code>swift_menu_duplicator_new_menu_name<\/code> to override the default \"(Copy)\" suffix<\/li>\n<\/ul>\n\n<h3>Snapshot Revisions<\/h3>\n\n<ul>\n<li><strong>Auto-snapshot<\/strong> \u2014 a snapshot is saved automatically before every menu save<\/li>\n<li><strong>Manual snapshots<\/strong> \u2014 save named snapshots from the menu editor at any time<\/li>\n<li><strong>Browse &amp; restore<\/strong> \u2014 view all snapshots in an expandable panel and restore with one click<\/li>\n<li><strong>Housekeeping<\/strong> \u2014 delete individual snapshots you no longer need<\/li>\n<\/ul>\n\n<h3>Menu Manager (Appearance \u2192 Menu Manager)<\/h3>\n\n<ul>\n<li>Dedicated page listing every menu on the site in a sortable WP_List_Table<\/li>\n<li><strong>Bulk duplicate<\/strong> \u2014 clone multiple menus at once<\/li>\n<li><strong>Bulk export<\/strong> \u2014 download selected menus as a single ZIP archive<\/li>\n<li><strong>Bulk delete<\/strong> \u2014 remove multiple menus in one action<\/li>\n<li>Row actions \u2014 duplicate or export individual menus directly from the list<\/li>\n<\/ul>\n\n<h3>JSON Export \/ Import<\/h3>\n\n<ul>\n<li>Export any menu to a portable JSON file (via admin or REST API)<\/li>\n<li>Import from a JSON file upload or paste JSON directly into the text area<\/li>\n<li><strong>URL find &amp; replace<\/strong> \u2014 swap domain names during import for staging \u2192 production migrations<\/li>\n<li><strong>Dry-run preview<\/strong> \u2014 review what will be imported before making any changes to the database<\/li>\n<\/ul>\n\n<h3>Multisite Support<\/h3>\n\n<ul>\n<li>Copy any menu to another site in your WordPress Multisite network<\/li>\n<li>Automatic URL rewriting in item URLs when copying across sub-sites<\/li>\n<\/ul>\n\n<h3>REST API<\/h3>\n\n<p>Full REST API at <code>\/wp-json\/cmd\/v1\/<\/code> for headless and block-editor integrations:<\/p>\n\n<ul>\n<li><code>POST \/menus\/{id}\/duplicate<\/code> \u2014 duplicate a menu (optional <code>name<\/code> parameter)<\/li>\n<li><code>GET  \/menus\/{id}\/export<\/code> \u2014 export a menu as a JSON payload<\/li>\n<li><code>POST \/menus\/{id}\/items\/{item_id}\/duplicate<\/code> \u2014 duplicate a single menu item<\/li>\n<\/ul>\n\n<p>Permission is controlled by the <code>swmd_rest_permission<\/code> filter (defaults to <code>edit_theme_options<\/code>).<\/p>\n\n<h3>WP-CLI<\/h3>\n\n<p>Full command-line support under the <code>wp swift-menu-duplicator<\/code> command group:<\/p>\n\n<ul>\n<li><code>wp swift-menu-duplicator duplicate &lt;menu-id&gt; [--name=&lt;name&gt;]<\/code> \u2014 duplicate a menu<\/li>\n<li><code>wp swift-menu-duplicator export &lt;menu-id&gt; [--output=&lt;file&gt;]<\/code> \u2014 export to JSON<\/li>\n<li><code>wp swift-menu-duplicator import &lt;file&gt; [--name=&lt;name&gt;] [--find=&lt;str&gt;] [--replace=&lt;str&gt;] [--dry-run] [--porcelain]<\/code> \u2014 import from JSON<\/li>\n<li><code>wp swift-menu-duplicator copy-to-site &lt;menu-id&gt; --target-blog=&lt;id&gt; [--name=&lt;name&gt;] [--find=&lt;str&gt;] [--replace=&lt;str&gt;]<\/code> \u2014 copy to a sub-site<\/li>\n<\/ul>\n\n<h3>Multilingual Compatibility<\/h3>\n\n<ul>\n<li><strong>WPML<\/strong> \u2014 translation meta keys (<code>_icl_lang_duplicate_of<\/code>, <code>wpml_language<\/code>, etc.) are stripped from duplicated items automatically<\/li>\n<li><strong>Polylang<\/strong> \u2014 language meta keys (<code>_pll_synced_taxonomies<\/code>, <code>_pll_menu_language<\/code>, etc.) are stripped from duplicated items automatically<\/li>\n<li>Additional keys can be excluded via the <code>swmd_compat_excluded_meta_keys<\/code> filter<\/li>\n<\/ul>\n\n<h3>Developer Hooks<\/h3>\n\n<ul>\n<li><code>swift_menu_duplicator_new_menu_name<\/code> \u2014 customise the default duplicate name<\/li>\n<li><code>swmd_rest_permission<\/code> \u2014 control REST API access<\/li>\n<li><code>swmd_before_duplicate_item<\/code> \/ <code>swmd_after_duplicate_menu_item<\/code> \u2014 fired around item duplication<\/li>\n<li><code>swmd_after_import_menu<\/code> \u2014 fired after a successful import<\/li>\n<li><code>swmd_item_meta_keys<\/code> \u2014 control which meta keys are copied<\/li>\n<li><code>swmd_compat_excluded_meta_keys<\/code> \u2014 extend the multilingual meta exclusion list<\/li>\n<li><code>wp_update_nav_menu<\/code> \u2014 triggers auto-snapshot before every menu save<\/li>\n<\/ul>\n\n<h3>Security<\/h3>\n\n<ul>\n<li>All AJAX actions verified with nonces and <code>edit_theme_options<\/code> capability checks<\/li>\n<li>All output escaped; all input sanitized<\/li>\n<li>Database queries use <code>$wpdb-&gt;prepare()<\/code> \u2014 no string concatenation<\/li>\n<li>REST API permission is filterable but defaults to <code>edit_theme_options<\/code><\/li>\n<li>WordPress Filesystem API used for all file read\/write\/delete operations<\/li>\n<\/ul>\n\n<p><strong>Requirements<\/strong><\/p>\n\n<ul>\n<li>WordPress 6.0 or higher<\/li>\n<li>PHP 7.4 or higher<\/li>\n<li>User with <code>edit_theme_options<\/code> capability<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>swift-menu-duplicator<\/code> directory to <code>\/wp-content\/plugins\/<\/code>.<\/li>\n<li>Activate the plugin through <strong>Plugins \u2192 Installed Plugins<\/strong>.<\/li>\n<li>Go to <strong>Appearance \u2192 Menus<\/strong>, select a menu, and click <strong>Duplicate Menu<\/strong> in the footer.<\/li>\n<li>For bulk management, snapshots, and import, visit <strong>Appearance \u2192 Menu Manager<\/strong>.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20it%20copy%20theme%20location%20assignments%3F\"><h3>Does it copy theme location assignments?<\/h3><\/dt>\n<dd><p>No. Theme location assignments are site-specific and intentionally not copied, so the duplicate does not silently replace an active menu in any location.<\/p><\/dd>\n<dt id=\"what%20happens%20to%20sub-menu%20items%3F\"><h3>What happens to sub-menu items?<\/h3><\/dt>\n<dd><p>All parent-child relationships are preserved exactly. The plugin uses a two-pass approach: items are cloned first, then parent ID references are re-mapped to the newly created item IDs.<\/p><\/dd>\n<dt id=\"can%20i%20rename%20the%20duplicate%20before%20it%20is%20created%3F\"><h3>Can I rename the duplicate before it is created?<\/h3><\/dt>\n<dd><p>Yes. A name field is shown in the duplicate modal. You can also change the default suffix globally by filtering <code>swift_menu_duplicator_new_menu_name<\/code>.<\/p><\/dd>\n<dt id=\"is%20it%20compatible%20with%20wpml%20or%20polylang%3F\"><h3>Is it compatible with WPML or Polylang?<\/h3><\/dt>\n<dd><p>Yes. Translation and language meta keys are automatically stripped from duplicated items so the copy starts as a clean, language-neutral menu.<\/p><\/dd>\n<dt id=\"is%20it%20compatible%20with%20woocommerce%20%2F%20hpos%3F\"><h3>Is it compatible with WooCommerce \/ HPOS?<\/h3><\/dt>\n<dd><p>Yes. The plugin only interacts with <code>nav_menu_item<\/code> posts and the <code>nav_menu<\/code> taxonomy. It has no dependency on WooCommerce or its High-Performance Order Storage.<\/p><\/dd>\n<dt id=\"can%20i%20duplicate%20a%20menu%20that%20contains%20draft%20items%3F\"><h3>Can I duplicate a menu that contains draft items?<\/h3><\/dt>\n<dd><p>Yes. All items are duplicated regardless of their post status.<\/p><\/dd>\n<dt id=\"how%20do%20i%20use%20the%20rest%20api%3F\"><h3>How do I use the REST API?<\/h3><\/dt>\n<dd><p>Authenticate with a cookie session or an Application Password, then send:<\/p>\n\n<pre><code>POST \/wp-json\/cmd\/v1\/menus\/{menu_id}\/duplicate\n<\/code><\/pre>\n\n<p>The response includes the new menu's <code>id<\/code>, <code>name<\/code>, and <code>edit_url<\/code>.<\/p><\/dd>\n<dt id=\"how%20do%20i%20migrate%20menus%20between%20environments%3F\"><h3>How do I migrate menus between environments?<\/h3><\/dt>\n<dd><p>Export the source menu to JSON (admin UI or <code>wp swift-menu-duplicator export<\/code>), transfer the file, then import it on the target site. Use the find\/replace fields to rewrite domain-specific URLs during import.<\/p><\/dd>\n<dt id=\"what%20capability%20is%20required%3F\"><h3>What capability is required?<\/h3><\/dt>\n<dd><p>edit_theme_options for all duplication, snapshot, export, and import actions. Multisite copy-to-site additionally requires <code>manage_options<\/code> on the target sub-site.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Fix: WP-CLI command renamed from <code>wp menu-duplicator<\/code> to <code>wp swift-menu-duplicator<\/code> for consistency with the plugin slug.<\/li>\n<li>Fix: <code>composer.lock<\/code> was excluded by <code>.gitignore<\/code> glob pattern causing the SVN deploy workflow to fail.<\/li>\n<li>Fix: Short description trimmed to satisfy the WordPress.org 150-character limit.<\/li>\n<li>Tested up to WordPress 7.0.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<li>One-click menu duplication from the WordPress menu editor with hierarchy preserved.<\/li>\n<li>Duplicate individual menu items from the editor.<\/li>\n<li>Snapshot system: auto-snapshot before every save, manual snapshots, restore and delete.<\/li>\n<li>Appearance \u2192 Menu Manager page with sortable table, bulk duplicate, bulk export (ZIP), and bulk delete.<\/li>\n<li>JSON export and import with URL find &amp; replace and dry-run preview.<\/li>\n<li>Multisite support: copy menus to any sub-site with optional URL rewriting.<\/li>\n<li>REST API at <code>\/wp-json\/cmd\/v1\/<\/code> \u2014 duplicate menu, export menu, duplicate item.<\/li>\n<li>WP-CLI command group <code>wp swift-menu-duplicator<\/code> \u2014 duplicate, export, import, copy-to-site.<\/li>\n<li>WPML and Polylang compatibility \u2014 translation and language meta stripped from duplicates.<\/li>\n<li>Developer hooks and filters throughout for extensibility.<\/li>\n<\/ul>","raw_excerpt":"Duplicate WordPress menus in one click. Snapshot revisions, export\/import JSON, bulk-manage all menus, copy across Multisite, automate with WP-CLI.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/292190","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=292190"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/mralaminahamed"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=292190"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=292190"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=292190"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=292190"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=292190"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=292190"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}