Adding BuddyPress Custom Pages to Profiles

BuddyPress comes with all the profile and group pages it needs to access core settings and content. Sometimes you add a plugin to your site that’s not a BuddyPress plugin but you want to have a page on the profile to display this extra content. If you are a plugin developer, you can add support for BuddyPress using this same technique. Adding BuddyPress custom pages to profiles doesn’t have to be complicated!

Let’s say you have a portfolio plugin and you want to put a tab/page on a user profile and include the portfolio items. If your portfolio items are a custom post type then you can add a post loop on the page and pass in a query for the displayed BuddyPress user.

The following image is what we will accomplish in this tutorial:


Sometimes you add a plugin to your site that’s not a BuddyPress plugin, but you want to have a page on the profile to display this extra content.

Custom Profile Tab

Profile tabs are created by passing and array or arguments to bp_core_new_nav_item(). You can specify the name on the tab, the slug when you visit this page, the position in relation to the other tabs, css id and the callback function that runs when a user visits this URL. The position is the placement in the user navigation. Navigation items are positioned by incremented of ten. We pass fifty and that would be in the 5th position. If you wanted an item in between 5th and 6th, you can pass 51-59. The argument 'show_for_displayed_user'  is for a profile tab you only want a logged in user to see on their on profile.

function bp_custom_user_nav_item() {
    global $bp;

    $args = array(
            'name' => __('Portfolio', 'buddypress'),
            'slug' => 'portfolio',
            'default_subnav_slug' => 'portfolio',
            'position' => 50,
            'show_for_displayed_user' => false,
            'screen_function' => 'bp_custom_user_nav_item_screen',
            'item_css_id' => 'portfolio'

    bp_core_new_nav_item( $args );
add_action( 'bp_setup_nav', 'bp_custom_user_nav_item', 99 );


Screen Callback Function

Mentioned previously, you create a call back function that runs when a user visits the page. In this function you add an action to a function that does the rendering. Also, you can load a default template that contains the walls and ceiling of the profile page. This plugins.php file contains the member header and user navigation. It makes it super easy get a page up and then fill in the content area. If you were to load your own template file you’d lose the member header and user navigation. So, stick with plugins.php!

The 'default_subnav_slug' argument is to set which subnavigation item you want to land on when clicking the tab. You can choose to add subpages to a page, pass in 'parent_slug' argument and bp_core_new_nav_item() will make the page a subpage.

How does this actually work? You hook your render function to ‘bp_template_content’, in the plugins.php template that loads there is a do_action for 'bp_template_content' and then the render function shows your content.

function bp_custom_user_nav_item_screen() {
    add_action( 'bp_template_content', 'bp_custom_screen_content' );
    bp_core_load_template( apply_filters( 'bp_core_template_plugin', 'members/single/plugins' ) );

Screen Content Function

In the callback function there is an action 'bp_template_content'  that we hook our render function too. In this function is where you put the content you want to display.  This is a user profile so you will want to make the content pertain to the displayed user.

function bp_custom_screen_content() {

   echo 'the custom content. 
    You can put a post loop here, 
    pass $user_id with bp_displayed_user_id()';


BuddyPress internal APIs make it trivial to add custom pages. Check out this simple example plugin that includes the code above. If you have any issues comment below and I’ll try to help out.


15 thoughts on “Adding BuddyPress Custom Pages to Profiles

  1. Wow, thank you for doing this! I’ve been looking for something like this for a while. I especially appreciate it in plugin form.

    Thanks again!


      1. Thats because github puts gists in a folder. Unzip it and either re-zip or place just the file to your plugins folder

  2. Hey there! This was just what I was looking for! Well it covers half of my issue 😛

    I was wondering in the new custom page can a person enter in html and have it load & show on their profile?

    I want them to be able to add a shortcode as the Yotti YouTube plugin allows you to simply add the short code but change it to their own youtube channel link e.g.

  3. Been looking for this for ages and it works great at adding the pages,
    MY question is this, I can add one page to the menu but I need to add several pages to the menu. I tried a seperate plugin for each page but get an error

    Fatal error: Cannot redeclare bp_custom_user_nav_item() (previously declared in /homepages/11/d627857689/htdocs/NineteenTenWebsite/wp-content/plugins/AddPhotoshootsToBuddyPress/AddPhotoshootsToBuddyPress.php:17) in /homepages/11/d627857689/htdocs/NineteenTenWebsite/wp-content/plugins/AddPrintsToBuddyPress/AddPrintsToBuddyPress.php on line 29

    How would I go about adding more than 1 page, each showing it’s own unique information (Custom Post Type)

  4. It works perfectly. It also updates to my requirements.
    But every time I change something in the file through the Editor, I get a message “No such file exists! Double check the name and try again.”
    Although the changes i made really do go through.

  5. Useful post Ryan.
    I would associate a custom post type (Portfolio in your example), to Groups. But how to join the portfolio id to the group id?

  6. Useful post Ryan. Now, how may I join a group to a custom post type (the portfolio of your example?) without passing by user? I would join a group id to a portfolio id. Thanks

Have a comment?

Your email address will not be published. Required fields are marked *

accessibilityadminaggregationanchorarrow-rightattach-iconbackupsblogbookmarksbuddypresscachingcalendarcaret-downcartunifiedcouponcrediblecredit-cardcustommigrationdesigndevecomfriendsgallerygoodgroupsgrowthhostingideasinternationalizationiphoneloyaltymailmaphealthmessagingArtboard 1migrationsmultiple-sourcesmultisitenewsnotificationsperformancephonepluginprofilesresearcharrowscalablescrapingsecuresecureseosharearrowarrowsourcestreamsupporttwitchunifiedupdatesvaultwebsitewordpress