# Duplicate a Navigation Menu

> Adds a "Duplicate this menu" button to Appearance > Menus that copies the selected classic menu with all its items and nesting, handy for trying a new structure safely.

- Type: PHP
- Runs: Admin only
- Category: [Admin](https://wpide.com/library/category/admin/)
- Tags: menus, duplicate, navigation
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/admin-duplicate-nav-menu/

## Code

```php
add_action( 'admin_footer-nav-menus.php', function () {
    $menu_id = isset( $_REQUEST['menu'] ) ? absint( $_REQUEST['menu'] ) : absint( get_user_option( 'nav_menu_recently_edited' ) );
    if ( ! $menu_id || ! is_nav_menu( $menu_id ) ) {
        return;
    }
    $url = wp_nonce_url( admin_url( 'admin-post.php?action=wpide_duplicate_menu&menu=' . $menu_id ), 'wpide_duplicate_menu_' . $menu_id );
    ?>
    <script>
    ( function () {
        var target = document.querySelector( '.major-publishing-actions .publishing-action' );
        if ( ! target ) { return; }
        var link = document.createElement( 'a' );
        link.className = 'button';
        link.style.marginRight = '6px';
        link.href = <?php echo wp_json_encode( $url ); ?>;
        link.textContent = 'Duplicate this menu';
        target.insertBefore( link, target.firstChild );
    } )();
    </script>
    <?php
} );

add_action( 'admin_post_wpide_duplicate_menu', function () {
    $menu_id = isset( $_GET['menu'] ) ? absint( $_GET['menu'] ) : 0;
    check_admin_referer( 'wpide_duplicate_menu_' . $menu_id );
    if ( ! current_user_can( 'edit_theme_options' ) || ! is_nav_menu( $menu_id ) ) {
        wp_die( 'Not allowed.', 403 );
    }

    $source = wp_get_nav_menu_object( $menu_id );
    $new_id = wp_create_nav_menu( $source->name . ' (Copy)' );
    if ( is_wp_error( $new_id ) ) {
        wp_die( esc_html( $new_id->get_error_message() ) );
    }

    $map = array();
    foreach ( (array) wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'any' ) ) as $item ) {
        $map[ $item->ID ] = wp_update_nav_menu_item( $new_id, 0, array(
            'menu-item-object-id'   => $item->object_id,
            'menu-item-object'      => $item->object,
            'menu-item-type'        => $item->type,
            'menu-item-title'       => $item->title,
            'menu-item-url'         => $item->url,
            'menu-item-description' => $item->description,
            'menu-item-attr-title'  => $item->attr_title,
            'menu-item-target'      => $item->target,
            'menu-item-classes'     => implode( ' ', (array) $item->classes ),
            'menu-item-xfn'         => $item->xfn,
            'menu-item-position'    => $item->menu_order,
            'menu-item-parent-id'   => $item->menu_item_parent ? ( $map[ $item->menu_item_parent ] ?? 0 ) : 0,
            'menu-item-status'      => 'publish',
        ) );
    }

    wp_safe_redirect( admin_url( 'nav-menus.php?action=edit&menu=' . (int) $new_id ) );
    exit;
} );
```

## Notes

The copy is not assigned to any theme location until you choose one.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Duplicate a Navigation Menu" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
