# Create custom store layouts

> [!NOTE]
> **Note:** New integration shouldn't create custom store layouts but integrate the [managed Google Play
> iframe](https://developers.google.com/android/work/play/emm-api/managed-play-iframe). Embedding the managed Google Play directly in your EMM console offers to customers a unified mobility management experience.

Managed Google Play lets you design and create store layouts for your enterprise
customers. You can customize a store layout by grouping apps into clusters,
setting up store pages, and adding quick links that provide access to multiple
pages within the store.

All the apps that are made available to an end user in the managed Google Play
store must first be approved by an IT admin, approved for the user, and added to
a cluster. (See [Adding apps to a store layout](https://developers.google.com/android/work/play/emm-api/store-layout#adding_apps_to_a_store_layout) for more details about this
process).

## Elements of a store layout

A store layout typically consists of a series of pages displayed to users in
managed Google Play. Each page can contain one or more groups of apps, referred
to as clusters. Each cluster contains one or more apps.

Clusters let you group related apps. For example, you can create a page for
work-related apps that contains an *Essentials* cluster and a *Getting Things
Done* cluster. The Essentials cluster could contain apps such as Notepad+,
Google Slides, and so on. The Getting Things Done cluster could include apps
like OneNote, Wunderlist, Any.do, and other tracking, calendar, and
meeting-planning apps (see Figure 1).

When you create a page, you can also add up to 10 quick links at the top of the
page. Quick links let users jump to other pages. For example, Figure 1 shows
quick links for Business, Communications, and Finance pages.

Figure 1 shows some the key elements of a store layout as seen on a device:
![A sample screen from a user device, showing the elements of a store
layout including quick links, pages, and clusters of apps.](https://developers.google.com/static/android/work/play/emm-api/store_layout_figure_1.png) Figure 1 - Sample screen from a user device

- **Quick links**: Optional links that provide access to other pages. Quick links take the name of the page they point to.
- **Page**: A named, vertically scrollable page comprising clusters of apps.
- **Cluster** (also called *collection*): A named, horizontally scrollable carousel of apps. Expands to full page if page contains a single cluster (or click "More" to make vertically scrollable).

### Limitations of store layout elements

When designing and implementing store layouts for your customers, keep these
limits in mind (most of these limits are due to principles of good UI design):

- 100 apps per cluster
- 30 clusters per page
- 10 quick links per page
- 100 pages per store
- 1,000 products (approved apps) per enterprise

### Localized page and cluster names

The managed Google Play store layout supports localized names for store pages
and store clusters. When you create a page or cluster you provide a list of
supported locales, as [IETF language tags](http://www.w3.org/International/articles/language-tags/), and associated localized names.
If a user's locale is not on the supported list, the system chooses the closest
match available. For example, if en-GB is not available the system chooses en-US
instead. If no close match is available, the system chooses the first name on
the list.

## Adding apps to a store layout

All apps present in `policy.productPolicy` are added automatically if an
enterprise is using a basic store layout. If an enterprise is using a custom
store layout, apps only present in the custom layout and `productPolicy` list
will be displayed on a device. All items present in `policy.productPolicy` are
searchable in the Play Store.

For an end user to install an app from the managed Google Play store, the app
must be compatible with the user's device and meet the following condition:

- Added to the user's allow list (using [`policy.productPolicy` on the device
  resource](https://developers.google.com/android/work/play/emm-api/v1/devices)) AND `policy.productAvailabilityPolicy` is set to `WHITELIST`, OR `policy.productAvailabilityPolicy` is set to `ALL` (allowing the search and installation of any app).

A user can use the search feature built into managed Google Play to find and
install any app that meets these conditions. However, the app will only be
visible in a basic store layout or if you have added the app to a
[collection/cluster](https://developers.google.com/android/work/play/emm-api/managed-play-iframe#organize-apps).

> [!NOTE]
> **Note:** If a user already owns an approved app that belongs to a cluster, the app will be searchable in the managed Google Play store, but it won't appear as part of a cluster unless it's in the user's allow list.

### Apps with revoked approval

Administrators can unapprove an app (revoke its approval) at any time. Apps with
revoked approval can still be added to clusters and users' allow lists, but
users won't see them or have the ability to install them from the managed Google
Play store. If an app with revoked approval is re-approved, the app will be made
available to users again in the managed Google Play store.

## Basic store layout

By default, a [basic store layout](https://developers.google.com/android/work/play/emm-api/v1/enterprises/setStoreLayout) is enabled for each of your customers. The
basic layout has 1 page and 1 cluster, showing a maximum of 1000 apps. Apps on
the page are sorted in order of their `product ID` value. If you create a custom
store layout (by setting `storeLayoutType ="custom"`), the basic store layout is
disabled.

## Create custom store layouts

EMMs can create custom store layouts for each of their enterprise customers.
Custom store layouts let you set up clusters of apps, add specific clusters to
pages, and specify quick links. Because you define the apps that make up each
cluster, you can use clusters to group related apps (for example, "Essentials"
and "Getting Things Done"). Users see only those apps whose permissions have
been accepted by the IT admin.

The [Google Play EMM API reference](https://developers.google.com/android/work/play/emm-api/v1) has information on the resources and
associated methods you use to create a custom store layout, specifically,
[Storelayoutpages](https://developers.google.com/android/work/play/emm-api/v1/storelayoutpages) and [Storelayoutclusters](https://developers.google.com/android/work/play/emm-api/v1/storelayoutclusters). The steps outlined in the
sections below walk you through a basic example.

## Programming tasks

To create a custom managed Google Play store layout for your customers, you
must:

1. Create a page
2. Create one or more clusters inside the pages
3. Set the homepage

At minimum, you must create at least one page consisting of one cluster for a
store layout, and the cluster must contain at least one app. You must also set
the homepage. If you create more than one page, you have the option to set quick
links to display across the top of each page.

The programming tasks for creating a custom managed Play store layout are
described below, followed by a complete [example](https://developers.google.com/android/work/play/emm-api/store-layout#example) of a store layout.

### Create a page

A page consists of one or more clusters. Each cluster contains at least one app.
Pages are created for specific enterprises, so you must invoke operations on
specific enterprise instances (`enterpriseId`). You can provide a user-friendly
name and localization information for each page, along with a list of `pageId`s
that users can reach from the page. The new page is created with the `insert`
operation ([Storelayoutpages.insert](https://developers.google.com/android/work/play/emm-api/v1/storelayoutpages/insert)) as shown here:

    public StorePage createPage(String enterpriseId, String name)
        throws IOException {
      List<LocalizedText> names =
          ImmutableList.of(
              new LocalizedText().setLocale("en").setText(name));
      StorePage storePage = new StorePage();
      storePage.setName(names);
      return androidEnterprise.storelayoutpages()
        .insert(enterpriseId, storePage)
        .execute();
    }

> [!NOTE]
> **Note:** If you create more than one page, you can use quick links to provide quick access among them. If you do create more than one page, be sure to link to all pages, because without a link to it, a page is not accessible. In other words, managed Play doesn't prevent you from creating orphan pages.

### Create a cluster

> [!IMPORTANT]
> **Key Point:** You can also support cluster creation by embedding [the
> managed Google Play iframe](https://developers.google.com/android/work/play/emm-api/managed-play-iframe#organize-apps) into your console.

Clusters contain groups of apps. The cluster is created first, and then it can
be added to a page. To create a cluster, invoke the `insert` operation of
[Storelayoutclusters](https://developers.google.com/android/work/play/emm-api/v1/storelayoutclusters) and pass values for these properties:

- A list of the `productId`s that the cluster should contain (for example, the `productId` for Gmail is `app:com.google.android.gm`)
- A user-friendly name for the cluster, such as "Getting Things Done"
- The `enterpriseId` that should be associated with the cluster
- The `pageId` (for the page that should contain the cluster)
- The cluster's placement on the page (first, second, and so on)

Here's an example:

    private String insertCluster(String enterpriseId, String pageId, String name,
        List<String> productIds, String orderInPage) throws IOException {
      StoreCluster storeCluster = new StoreCluster();
      storeCluster.setName(
          ImmutableList.of(
              new LocalizedText().setLocale("en").setText(name)));
      storeCluster.setProductId(productIds);
      storeCluster.setOrderInPage(orderInPage);
      return androidEnterprise.storelayoutclusters()
        .insert(enterpriseId, pageId, storeCluster)
        .execute()
        .getId();
    }

### Set the homepage

The first page that displays in managed Google Play on a user's device is
the homepage. As an EMM you define a homepage for each of your customers. The
page is always visible, even when it is empty, and it cannot be deleted.

In this example, the ID of the homepage is fetched for the specified
`enterpriseId`:

    public StoreLayout getStoreLayout(String enterpriseId) throws IOException {
      return androidEnterprise
        .enterprises()
        .getStoreLayout(enterpriseId)
        .execute();
    }

This next example sets the homepage for a customer by providing the
customer's `enterpriseId` and the `pageId` of that customer's
homepage:

    public StoreLayout setStoreLayout(String enterpriseId, String homepageId)
        throws IOException {
      StoreLayout storeLayout = new StoreLayout();
      storeLayout.setHomepageId(homepageId);

      return androidEnterprise
        .enterprises()
        .setStoreLayout(enterpriseId, storeLayout)
        .execute();
    }

### Set quick links (optional)

> [!CAUTION]
> **Caution:** Creating clusters (also called *collections*) in Store builder will clear any existing quick links. To restore them, call [`StoreLayoutPages.Update`](https://developers.google.com/android/work/play/emm-api/v1/storelayoutpages/update).

Quick links display at the top of each page, enabling users to easily navigate
among pages in the store. To use quick links, first obtain the `pageId` for the
page (returned by `insert`) and add the link to the page. For example, if you
create three pages whose `pageId`s are `p1`, `p2`, `p3`, you can add quick links
from the first page to the other two pages with the following:

    StorePage storePage = new StorePage();
    storePage.setName(
        ImmutableList.of(new LocalizedText().setLocale("en").setText(title)));
    storePage.setLink(ImmutableList.of("p2", "p3");
    return androidEnterprise.storelayoutpages()
      .update(enterpriseId, "p1", storePage)
      .execute();

## Example

Here's a complete example that creates a basic store consisting of three
inter-linked pages. Clusters of similar apps make up each page. Each page is
created by specifying the customer's `enterpriseId` and setting the page `name`
only, to obtain its `pageId` that is then used to create a quick link to the
page.

    // Create a basic page and return the pageId.
    private String insertPage(String enterpriseId, String title,
        List<String> links) throws IOException {
      List<LocalizedText> names =
          ImmutableList.of(new LocalizedText().setLocale("en").setText(title));
      StorePage page = new StorePage();
      page.setName(names);
      page.setLink(links);
      return enterprise.storelayoutpages().insert(enterpriseId, page).execute().getId();
    }

    public StoreLayout setStoreLayout(String enterpriseId, String homepageId)
        throws IOException {
      StoreLayout storeLayout = new StoreLayout();
      storeLayout.setHomepageId(homepageId);

      return androidEnterprise
          .enterprises()
          .setStoreLayout(enterpriseId, storeLayout)
          .execute();
    }

    private String insertCluster(String enterpriseId, String pageId, String name,
        List<String> productIds, String orderInPage) throws IOException {
      StoreCluster cluster = new StoreCluster();
      List<LocalizedText> names =
          ImmutableList.of(new LocalizedText().setLocale("en").setText(name));
      cluster.setName(names);
      cluster.setProductId(productIds);
      cluster.setOrderInPage(orderInPage);
      return androidEnterprise.storelayoutclusters()
          .insert(enterpriseId, pageId, cluster)
          .execute()
          .getId();
    }

    private void updatePage(String enterpriseId, String pageId, String title,
        List<String> links) throws IOException {
      List<LocalizedText> names =
          ImmutableList.of(new LocalizedText().setLocale("en").setText(title));
      StorePage page = new StorePage();
      page.setName(names);
      page.setLink(links);
      enterprise.storelayoutpages()
          .update(enterpriseId, pageId, page).execute();
    }

    private void makeStore(String enterpriseId) throws IOException {
      // Create the pages.
      String page1 = insertPage(enterpriseId, "Home");
      String page2 = insertPage(enterpriseId, "Productivity");
      String page3 = insertPage(enterpriseId, "Accounting");

      // Set the homepage (page that displays by default when store is opened).
      setStoreLayout(enterpriseId, page1);

      // Add the links to the pages. This makes a small tree.
      updatePage(enterpriseId, page1, "Home", ImmutableList.of(page2, page3));
      updatePage(enterpriseId, page2, "Productivity", ImmutableList.of(page1));
      updatePage(enterpriseId, page3, "Accounting", ImmutableList.of(page1));

      // Add clusters with contents.
      insertCluster(
          enterpriseId,
          page1,
          "Getting Things Done",
          ImmutableList.of(
              "app:com.mytodolist",
              "app:com.google.android.gm",
              "app:com.google.android.docs"),
          "1");
      insertCluster(
          enterpriseId,
          page1,
          "Strategy",
          ImmutableList.of(
              "app:com.myplanner",
              "app:com.stratego"),
          "2");
      insertCluster(
          enterpriseId,
          page2,
          "Editors",
          ImmutableList.of(
              "app:com.myeditor",
              "app:com.betteredit",
              "app:com.lazyguy"),
          "1");
      insertCluster(
          enterpriseId,
          page2,
          "Time Management",
          ImmutableList.of(
              "app:com.mytimetracker",
              "app:com.lazygal",
              "app:com.lazyguy"),
          "2");
      insertCluster(
          enterpriseId,
          page2,
          "Accounting",
          ImmutableList.of(
              "app:com.mymoney",
              "app:com.taxpro",
              "app:com.balances"),
          "3");
    }