I had the same problem and I have found a solution : Call the same page with a parameter and include the content depending on the paramter : if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } define(PLUG_NAME, "my_admin"); //hook to add an item in the menu admin add_action('admin_menu', 'my_admin_setup_menu'); function my_admin_setup_menu(){ //1st : title of the page, 2nd : title in the menu menu add_menu_page( 'My plugin page', 'My plugin', 'manage_options', 'my_admin', 'my_plugin_init' ); } function my_plugin_init(){ //links inside the page $page_link1="<a href=\"admin.php?page=".PLUG_NAME."&idp=1\">link 1</a>"; $page_link2="<a href=\"admin.php?page=".PLUG_NAME."&idp=2\">link 2</a>"; $page_link3="<a href=\"admin.php?page=".PLUG_NAME."&idp=3\">link 3</a>"; //get the id of the page we want to display // then we include the page if (isset($_GET['idp'])){ $page =(int) $_GET['idp']; switch ($page) { case 1: $page_inc="page1.php"; break; case 2: $page_inc="page2.php"; break; case 3: $page_inc="page3.php"; break; } include( plugin_dir_path( __FILE__ ) . $page_inc); }else{ echo "<h1>My plugin home</h1>"; //display the link in the main page echo $page_link1."<br/>"; echo $page_link2."<br/>"; echo $page_link3."<br/>"; } } ?>