You need a custom walker for the nav menu.
Basically, you add a parameter 'walker' to the wp_nav_menu() options and call an instance of an enhanced class:
wp_nav_menu( array ( 'menu' => 'main-menu', 'container' => FALSE, 'container_id' => FALSE, 'menu_class' => '', 'menu_id' => FALSE, 'depth' => 1, 'walker' => new Description_Walker ) );
The class Description_Walker extends Walker_Nav_Menu and changes the function start_el( &$output, $item, $depth, $args ) to look for $item->description.
A basic example:
/** * Create HTML list of nav menu items. * Replacement for the native Walker, using the description. * * @see https://wordpress.stackexchange.com/q/14037/ * @author fuxia */ class Description_Walker extends Walker_Nav_Menu { /** * Start the element output. * * @param string $output Passed by reference. Used to append additional content. * @param object $item Menu item data object. * @param int $depth Depth of menu item. May be used for padding. * @param array|object $args Additional strings. Actually always an instance of stdClass. But this is WordPress. * @return void */ function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) { $classes = empty ( $item->classes ) ? array () : (array) $item->classes; $class_names = join( ' ' , apply_filters( 'nav_menu_css_class' , array_filter( $classes ), $item ) ); ! empty ( $class_names ) and $class_names = ' class="'. esc_attr( $class_names ) . '"'; $output .= "<li id='menu-item-$item->ID' $class_names>"; $attributes = ''; ! empty( $item->attr_title ) and $attributes .= ' title="' . esc_attr( $item->attr_title ) .'"'; ! empty( $item->target ) and $attributes .= ' target="' . esc_attr( $item->target ) .'"'; ! empty( $item->xfn ) and $attributes .= ' rel="' . esc_attr( $item->xfn ) .'"'; ! empty( $item->url ) and $attributes .= ' href="' . esc_attr( $item->url ) .'"'; // insert description for top level elements only // you may change this $description = ( ! empty ( $item->description ) and 0 == $depth ) ? '<small class="nav_desc">' . esc_attr( $item->description ) . '</small>' : ''; $title = apply_filters( 'the_title', $item->title, $item->ID ); $item_output = $args->before . "<a $attributes>" . $args->link_before . $title . '</a> ' . $args->link_after . $description . $args->after; // Since $output is called by reference we don't need to return anything. $output .= apply_filters( 'walker_nav_menu_start_el' , $item_output , $item , $depth , $args ); } }
Or, alternatively as @nevvermind commented, you could inherit all the functionalities of the parent's start_el function and just append the description to $output:
function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) { parent::start_el( $output, $item, $depth, $args ); $output .= sprintf( '<i>%s</i>', esc_html( $item->description ) ); }
Sample output:

Now enable the description field in wp-admin/nav-menus.php to get the ability to edit this field. If you don’t WP just trashes your complete post content into it.

Further reading:
And that’s it.