Page Tabs

The POST and DELETE methods for the /PAGE-ID/tabs endpoint are deprecated. Please visit the Graph API Changelog for more information.

This guide explains how to get, create, manage, and delete Page Tabs using the Graph API.

Beginning June 30, 2022, access to the /PAGE-ID/tabs endpoint will be restricted to apps that have accessed it in the last 90 days.

Overview

Major brands, celebrities, and organizations use Facebook Pages as their social home on the web. Besides standard tabs like "About", "Events" or "Photos" you can add custom Page tabs via the Facebook platform. These custom Page tabs load content from your webserver using an iframe. Page tabs will only be displayed in the web UI. Mobile custom tabs are not supported at this time.

Limitations

Only Pages with 2000 or more likes can create custom Page tabs.

The amount of space available to your tab app is bounded by the outer context of Facebook. It may be configured to display with a width of 520 pixels (default) or 810 pixels.

Before You Start

To read Page Tabs, you will need:

  • A Page access token requested by a person who can perform the MANAGE task on the Page.
  • The pages_manage_metadata permission

If a person is not able to perform the task on the Page, you will need the following:

  • The Pages Public Content Access feature
When using the Page Public Content Access feature, use a system user access token to avoid rate limiting issues.

To create Page Tabs, you will need:

  • A Page access token requested by a person who can perform the MANAGE task on the Page.
  • The pages_manage_metadata permission

Create a Tab

Send a POST request to the /{page-id}/tabs edge:

curl -i -X POST "https://graph.facebook.com/{page-id}/tabs?
        custom_name=My Custom Tab&
        tab={app_id}&
        access_token={page-access-token}"
GraphRequest request = GraphRequest.newPostRequest(
  accessToken,
  "/{page-id}/tabs",
  new JSONObject("{\"custom_name\":\"My Custom Tab\",\"tab\":\"app_{app_id}\"}"),
  new GraphRequest.Callback() {
    @Override
    public void onCompleted(GraphResponse response) {
      // Insert your code here
    }
});
request.executeAsync();
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
    initWithGraphPath:@"/{page-id}/tabs"
           parameters:@{ @"custom_name": @"My Custom Tab",@"tab": @"app_{app_id}",}
           HTTPMethod:@"POST"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
    // Insert your code here
}];
FB.api(
  '/{page-id}/tabs',
  'POST',
  {"custom_name":"My Custom Tab","tab":"app_{app_id}"},
  function(response) {
      // Insert your code here
  }
);
try {
  // Returns a `FacebookFacebookResponse` object
  $response = $fb->post(
    '/{page-id}/tabs',
    array (
      'custom_name' => 'My Custom Tab',
      'tab' => 'app_{app_id}'
    ),
    '{access-token}'
  );
} catch(FacebookExceptionsFacebookResponseException $e) {
  echo 'Graph returned an error: ' . $e->getMessage();
  exit;
} catch(FacebookExceptionsFacebookSDKException $e) {
  echo 'Facebook SDK returned an error: ' . $e->getMessage();
  exit;
}
$graphNode = $response->getGraphNode();

On success, your app gets this response:

{
  "success": true
}

Use the UI

To add and manage tabs using the UI visit our Help Center.

Get Tab Information

Send a GET request to the /{page-id}/tabs endpoint:

curl -i -X GET "https://graph.facebook.com/{page-id}/tabs/?access_token={access=token}"
GraphRequest request = GraphRequest.newGraphPathRequest(
  accessToken,
  "/{page-id}/tabs/",
  new GraphRequest.Callback() {
    @Override
    public void onCompleted(GraphResponse response) {
      // Insert your code here
    }
});

request.executeAsync();
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
    initWithGraphPath:@"/{page-id}/tabs/"
           parameters:nil
           HTTPMethod:@"GET"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
    // Insert your code here
}];
FB.api(
  '/{page-id}/tabs/',
  'GET',
  {},
  function(response) {
      // Insert your code here
  }
);
try {
  // Returns a `FacebookFacebookResponse` object
  $response = $fb->get(
    '/{page-id}/tabs/',
    '{access-token}'
  );
} catch(FacebookExceptionsFacebookResponseException $e) {
  echo 'Graph returned an error: ' . $e->getMessage();
  exit;
} catch(FacebookExceptionsFacebookSDKException $e) {
  echo 'Facebook SDK returned an error: ' . $e->getMessage();
  exit;
}
$graphNode = $response->getGraphNode();

On success, your app gets this response:

{
  "data": [
    {
      "id": "19292868552/tabs/posts",
      "name": "Posts",
      "link": "/FacebookforDevelopers/posts/",
      "is_permanent": true,
      "position": 1,
      "is_non_connection_landing_tab": false
    },
    {
      "id": "19292868552/tabs/videos",
      "name": "Videos",
      "link": "/FacebookforDevelopers/videos/",
      "is_permanent": true,
      "position": 2,
      "is_non_connection_landing_tab": false
    },
    {
      "id": "19292868552/tabs/about",
      "name": "About",
      "link": "/FacebookforDevelopers/about/",
      "is_permanent": true,
      "position": 3,
      "is_non_connection_landing_tab": false
    },
...

Change the Position of a Tab

Send a POST request to the /{page-id}/tabs/{tab-name} endpoint and set the position parameter:

curl -i -X POST "https://graphfacebook.com/{page-id}/tabs/{tab-name}?
        position=5&
        access_token={page-access-token}"
GraphRequest request = GraphRequest.newPostRequest(
  accessToken,
  "/{page-id}/tabs/events",
  new JSONObject("{\"position\":\"5\"}"),
  new GraphRequest.Callback() {
    @Override
    public void onCompleted(GraphResponse response) {
      // Insert your code here
    }
});
request.executeAsync();
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
    initWithGraphPath:@"/{page-id}/tabs/events"
           parameters:@{ @"position": @"5",}
           HTTPMethod:@"POST"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
    // Insert your code here
}];
FB.api(
  '/{page-id}/tabs/events',
  'POST',
  {"position":"5"},
  function(response) {
      // Insert your code here
  }
);
try {
  // Returns a `FacebookFacebookResponse` object
  $response = $fb->post(
    '/{page-id}/tabs/events',
    array (
      'position' => '5'
    ),
    '{access-token}'
  );
} catch(FacebookExceptionsFacebookResponseException $e) {
  echo 'Graph returned an error: ' . $e->getMessage();
  exit;
} catch(FacebookExceptionsFacebookSDKException $e) {
  echo 'Facebook SDK returned an error: ' . $e->getMessage();
  exit;
}
$graphNode = $response->getGraphNode();

On success, your app gets this response:

{
  "success": true
}

Add an App to a Page

A person who manages a Facebook Page can download your tab app to their Page. You will be notified via a callback URL that someone has added your app to their Page. This does not require any extended permissions.

With JavaScript SDK

This dialog can be used with the JavaScript SDK by performing a full page redirect to a URL.

FB.ui({
  method: 'pagetab',
  redirect_uri: '{your-callback-url}'
}, function(response){});

The above example assumes that the person has already logged in to your app.

With URL Redirects

https://www.facebook.com/dialog/pagetab?
  app_id={your-app-id}
  &redirect_uri={your-callback-url}

You can use the following parameters in the redirect:

ParameterDescription

app_id

Required

The unique ID of your app.

redirect_uri

The URL a person is redirected to after they click a button on the dialog. Required when using URL redirection.

display

Determines how the dialog is rendered. Not available on mobile devices.

page

If you are using the URL redirect dialog implementation, then this will be a full page display, shown within Facebook.com.

iframe

If you are using the JavaScript SDK, this will default to a modal iframe type for people logged into your app or async when using within a game on Facebook.com, and a popup window for everyone else. You can also force the popup or page types when using the JavaScript SDK, if necessary.

Authorization and Customization

When your tab is loaded on Facebook, an HTTP POST request is made to your Secure Page Tab URL. This POST request will contain parameters including the signed_request parameter which you can use for authorization and customizing content for your Users.

Authorization

The signed_request is base64url encoded and signed with an HMAC version of your App Secret, based on the OAuth 2.0 spec. When your app receives the signed_request you will need to parse and verify it before it can be used. This is performed in three steps:

  1. Split the signed request into two parts delineated by a '.' character (eg. 238fsdfsd.oijdoifjsidf899)
  2. Decode the first part, the encoded signature, from base64url
  3. Decode the second part, the payload, from base64url and then decode the resultant JSON object

On success, the JSON object looks something like this:

{
   "oauth_token": "{user-access-token}",
   "algorithm": "HMAC-SHA256",
   "expires": 1291840400,
   "issued_at": 1291836800,
   "user_id": "218471"
}

Customization

If you want to customize the content shown to each User, include the app_data parameter in the original query. It might look like this:

https://www.facebook.com/{page-id}?sk=app_{app_id}&app_data={string-data}

You can use that to customize the content you render if you control the generation of the link.