Ok, the wp_nav_menu() echo is by default, therefore, to save it in a variable, you can do the same as with ordinary widgets - output buffering:
function custom_menu() { ob_start(); wp_nav_menu( array( 'theme_location' => 'product-menu' ) ); $menu = ob_get_contents(); ob_end_clean(); $var = '<div class="side-nav"> <div class="side-nav-menu product- nav"> <p>Products</p>' . $menu . ' </div></div>'; return $var; } add_shortcode("custom", "custom_menu");
That should work.
What you do is run the output buffer using ob_start(); , then everything that you echo inside gets into the buffer, then you display the contents of the buffer in the $menu variable and clear the buffer. Then you can safely use the $menu variable as you wish
source share