Customize Storefront

In Workspace 11 and later, you can customize the content your Storefront provides to the Store component. Customization includes:

  • Which items appear on the landing page

  • Properties of the buttons on the app content cards, including text, behavior, and whether a secondary set of buttons appears when a primary button is selected

How it works

A StorefrontLandingPageItem type lets you specify either navigation items or apps in any row of the Storefront landing page. For more information about the landing page layout, see the Storefront overview.

The primaryButton property of the App interface specifies a StoreButtonConfig object. The secondaryButtons property specifies an array of StoreButtonConfig objects. The title and action properties of the StoreButtonConfig object specify button text and behavior. A StoreCustomButtonActionPayload object adds any data that's required to complete the button action.

To dynamically update buttons, an updateAppCardButtons method is included in the StoreRegistration object that's returned by the register method of the Storefront API.

For information about landing pages and Storefront registration, see the Storefront overview.

Example

  1. Define the custom actions your platform wants to invoke from a Store button. This example defines three custom actions we'll then invoke from an App definition:

    import { init } from "@openfin/workspace-platform";
    await init(
      {
        customActions:
          {
            "requestAccess": async (payload: StoreCustomButtonActionPayload) => {
              const { appId } = payload;
              // requestAccess is a hypothetical long running function.
              await requestAccess(payload.appId);
            },
            "launchMoreInfo": async (payload: StoreCustomButtonActionPayload) => {
              // launchMoreInfo is a hypothetical function that does something with appid and a payload. 
              await launchMoreInfo(payload.appId, payload.data);
            },
            "launchApp": async (payload: StoreCustomButtonActionPayload) => {
              // launchApp is another hypothetical function that does something with appid and a payload. 
              await launchApp(payload.appId, payload.data);
            }
          }
      }
    );
    

    or, for buttons that are updated dynamically, something like the following:

    import { init } from "@openfin/workspace-platform";
    import { Storefront, StorefrontProvider} from "@openfin/workspace";
    
    const storeRegistration = await Storefront.register(...);
    
    await init(
      {
        customActions: {
            "requestAccess": async (payload: StoreCustomButtonActionPayload) => {
              registration.updateAppCardButtons({
                 appId: payload.appId,
                 primaryButton: {
                    ...payload.PrimaryButton,
                    title: "Requesting access...",
                    disabled: true
                },
                secondaryButtons: payload.SecondaryButtons
              });
            }
          }
      }
    );
    
  2. Include the primaryButton or secondaryButtons properties in your App definition. The following example omits other optional properties.

    Note that manifest and manifestType are no longer required properties. They are still supported, but depending on your App definition you can work with the action property of the StoreButtonConfig object instead.

    const sampleApp: App = {
      appId: 1,
      title: 'Sample app',
      icons: [
        {
          src: "FAVICON.ico"
        }
        ],
      publisher: WHO_OWNS_IT,
      primaryButton: {
        title: 'Request Access',
        action: {
          id: 'requestAccess'
        }
      },
      secondaryButtons: [
        {
          title: 'More Info',
          action: {
            id: 'launchMoreInfo',
            data: {
              additionalData: 'some data...'
            }
          }
        },
        {
          title: 'Launch App',
          action: {
            id: 'launchApp',
            data: {
              additionalData: 'start sample app ...'
            }
          }
        }
      ]
    };