Square Dashboard Add-Ons SDK Reference

A lightweight React SDK for rendering Add-ons.

The Square Seller Dashboard Add-Ons SDK (“Seller Dashboard SDK”) is a client SDK that provides APIs, React hooks, and TypeScript types to simplify the process of building add-ons.

Before you start

React is the supported rendering framework of choice for Add-ons. This guide assumes that you have some knowledge of React and React hooks. If you need a refresher, check out the React quick start guide before continuing with this guide.

SDK Package

The SDK package is @square/web-addons-dashboard. The package is intended for use on the Square Dashboard.

Under the package there are two exports.

  • /react Add-on React render function and API hooks to communcation with the Dashboard.
  • /errors Error utilities and types for error handling.

For the Developer Preview release

  • The SDK package is included with the Dashboard Add-ons CLI. The SDK package is not publicly accessible on npm.
  • The following functionality is provided:
    • Placement Render: The ability to render on the customer view, modal and blade placements of the Dashboard.
    • Placement Launch: Methods to launch secondary placements such as modal or blade from the initial constomer view placement.
    • Contextual Data: Context about the placement it is being rendered on (e.g. the Customer ID of the current customer if loaded on the Customer View).

The Add-on render function

render()

The render() function is used as the point of entry for an add-on’s view. The view module must export render() as the default function for successful render on a Dashboard placement. Upon render the placement specific Dashboard APIs will be provided as properties to the view. However hook usage us suggested.

 /**
   * The render function to be used to render an add-on view entry point.
   * @param App - the entry point component to render.
   */

const render = (
    App:
      | string
      | React.FunctionComponent<{ api: API }>
      | typeof React.Component<{ api: API }>,
  ) =>
  ({ api }: { api: API }) => React.JSX.Element;

APIs

Placements are injected with APIs to allow for communication with the Dashboard. The APIs are composed of global and contextual properties.

Shared Types

MaybeError

The MaybeError object is returned as a response upon execution of an SDK API. If a failure occurs when you try to retrieve properties from the dashboard, the response is an error. If a success occurs when retrieving properties, the response returns undefined.

type MaybeError = Error | undefined

ShallowProps

The ShallowProps interface represents a blade or modal’s props, which contains values of the following primitive types: boolean, string, or number.

type ShallowProps = Record<string, boolean | string | number>

Merchant

The merchant visiting the Dashboard. You can access this from the Global API, available via the placement’s hook, such as useCustomerviewApi()

type Merchant = {
 /**
  * The id of the merchant.
  */
  id: string;
};

AddonView

The Add-on view currently rendered.

type AddonView = {
  /**
   * The id of the add-on. This can be found in the add-on's manifest id field.
   */
  id: string;
  /**
   * This is the placement of the currently loaded add-on view.
   * for example 'square.dashboard.customer.view' 
   **/
  placement: string;
};

Global APIs

The GlobalAPI contains properties which are present for all Add-on views no matter the placement.

type GlobalAPI = {
  /**
   * Application modal properties.
   */
  modal: {
    /**
     * Opens an application modal loading the add-on view with a placement value of 'square.dashboard.modal' within the add-on manifest.
     * @param payload - The props to pass to the add-on modal view.
     */
    show(payload: { props?: ShallowProps | undefined }): Promise<MaybeError>;  
  };
  /**
   * Application blade properties.
   */
  blade: {
        /**
     * Opens an application blade loading the add-on view with a placement value of 'square.dashboard.blade' within the add-on manifest.
     * @param payload - The props to pass to the add-on blade view.
     */
    show(payload: { props?: ShallowProps | undefined }): Promise<MaybeError>;
  };
 /**
   * Properties of the currently loaded Add-on view.
   */
  addOnView: AddOnView;
  /**
   * Properties of the current Merchant.
   */
  merchant: Merchant;
};

Placement APIs

Placement APIs are composed of the GlobalAPI properties along with contextual properties of the placement.

BladeAPI

The BladeAPI holds a shallow property bag of values passed by the calling context.

type BladeAPI = {
  /**
   * The props passed to the blade view on show.
   */
  props: ShallowProps | undefined;
};

ModalAPI

The ModalAPI holds a shallow property bag of values passed by the calling context.

type ModalAPI = {
  /**
   * The props passed to the modal view on show.
   */
  props: ShallowProps | undefined;
};

CustomerViewAPI

The CustomerViewAPI holds details about the current customer in view from the dashboard. Some properties are subscribables which means when provided a subscriber will emit changes to the object as they take place.


type CustomerViewAPI = {
  /**
   * The customer currently in view.
   */
  customer: RemoteSubscribable<Customer>;
};

The Customer object provides details about a Square customer profile from the Customer directory. This object contains a customer’s unique ID.

/**
 * The details for a single customer.
 * See: https://developer.squareup.com/reference/square/customers-api/retrieve-customer
 */
type Customer = {
  /**
   * The id of the customer object.
   */
  id: string;
};

HomeWidgetsAPI

The HomeWidgetsAPI holds location filter details on the home view from the Dashboard. Some properties are subscribables which means when provided a subscriber will emit changes to the object as they take place.


type HomeWidgetsAPI = {
   /**
   * The location to filter by.
   */
  location: RemoteSubscribable<Location>;

  /**
   * The date range to filter by.
   */
  dateRange: RemoteSubscribable<DateRange>;
};
/**
 * The details for a location.
 * See: https://developer.squareup.com/reference/square/locations-api/retrieve-location
 * */
type Location = {
  /**
   * The id of the location object.
   */
  id: string;
};

type DateRange = {
  /**
   * The start date of the range.
   */
  start: Date;

  /**
   * The end date of the range.
   */
  end: Date;
};

ItemViewAPI

The ItemViewAPI holds item details on the item view from the dashboard. Some properties are subscribables which means when provided a subscriber will emit changes to the object as they take place.


type ItemViewAPI = {
  /**
   * The details for a catalog object.
   */
  catalogObject: RemoteSubscribable<CatalogObject | undefined>;
};
/**
 * The details for a catalog object.
 * See: https://developer.squareupstaging.com/explorer/square/catalog-api/retrieve-catalog-object
 */
type CatalogObject = {
  /**
   * The id of the catalog object.
   */
  id: string;
};

The next section explains how API hooks may be used in view components.

React API Hooks

The following examples show how to use the render() function to call the placement and helper React hooks in the customer view placement context. The customer view placement context is represented in customer-view.tsx.

useCustomerViewApi placement API hook

The useCustomerViewApi placement hook returns a customer view API. This API holds global properties such as modal and blade along with contextual properties such as customer.

// customer-view.tsx
import {
  render,
  useCustomerViewApi,
} from '@square/web-addons-dashboard/react';
import React from 'react';

export default render(() => {
  const { modal, blade, merchant, customer } = useCustomerViewApi();
});

useCustomerViewCustomer placement helper hook

The useCustomerViewCustomer helper hook is used to extract the customer as a value. This hook will update your component for you as the customer changes.

// customer-view.tsx
import {
  render
  useCustomerViewCustomer,
} from '@square/web-addons-dashboard/react';
import React from 'react';

export default render(() => {
  const customer = useCustomerViewCustomer();

  return (
    <Label>
      {customer.id}
    </Label>
  );
});

useHomeWidgetsApi placement API hook

The useHomeWidgetsApi placement hook returns a home widget view API. This API holds global properties such as modal and blade along with contextual properties such as filters.

// home-view.tsx
import {
  render,
  useHomeWidgetsApi,
} from '@square/web-addons-dashboard/react';
import React from 'react';

export default render(() => {
  const { modal, blade, merchant, location } = useHomeWidgetsApi();
});

useHomeWidgetsDateRange placement helper hook

The useHomeWidgetsDateRange helper hook is used to extract the date range filter as a value. This hook will update your component for you as the customer changes.

// home-view.tsx
import {
  render
  useHomeWidgetsDateRange,
  Text,
  Box,
} from '@square/web-addons-dashboard/react';
import React from 'react';

export default render(() => {
  const dataRange =   useHomeWidgetsDateRange();

  return (
    <Box>
      <Text>Date Range</Text>
      <Box>Start {dateRange.start.toDateString()}</Box>
      <Box>End {dateRange.end.toDateString()}</Box>
    </Box>
  );
});

useHomeWidgetsLocation placement helper hook

The useHomeWidgetsLocation helper hook is used to extract the location filter as a value. This hook will update your component for you as the customer changes.

// home-view.tsx
import {
  render
  useCustomerViewCustomer,
  Text,
  Box,
} from '@square/web-addons-dashboard/react';
import React from 'react';

export default render(() => {
  const customer = useCustomerViewCustomer();

  return (
    <Box>
      <Text>Location</Text>
      <Box>
        {location.id}
      </Box>
    </Box>
  );
});

useItemViewApi placement API hook

The useItemViewApi placement hook returns a item view API. This API holds global properties such as modal and blade along with contextual properties such as the catalog object.

// item-view.tsx
import {
  render,
  useItemViewApi,
} from '@square/web-addons-dashboard/react';
import React from 'react';

export default render(() => {
  const { modal, blade, merchant, catalogObject } = useItemViewApi();
});

useItemViewCatalogObject placement helper hook

The useItemViewCatalogObject helper hook is used to extract the catalog object as a value. This hook will update your component for you as the customer changes.

// item-view.tsx
import {
  render
  useItemViewCatalogObject,
  Text,
  Box,
} from '@square/web-addons-dashboard/react';
import React from 'react';

export default render(() => {
  const catalogObject = useItemViewCatalogObject();
  const text = catalogObject?.id ?? 'undefined';

  return (
    <Box >
      <Box>Catalog Object ID</Box>
      <Text>{text}</Text>
    </Box>
  );
});

useBladeApi placement API hook

The useBladeApi() returns the BladeAPI.

//blade.tsx
import { useBladeApi, render, Label } from '@square/web-addons-dashboard/react';
import React from 'react';

export default render(() => {
  const { props } = useBladeApi();
  return (
    <Label>
      {props.id}
    </Label>
  );
});

useModalApi placement API hook

The useModalApi() returns the ModalAPI

//modal.tsx
import { useModalApi, render, Label } from '@square/web-addons-dashboard/react';
import React from 'react';

export default render(() => {
  const { props } = useModalApi();
  return (
    <Label>
      {props.id}
    </Label>
  );
});

useDirty helper hook

The useDirty helper hook is used to help maintain dirty state against an initial value as it changes. Providing an initialValue then using the setValue function to change the current value to something not equal to initialValue will result in isDirty changing from false to true. setInitialValue can be used to change the initial value to compare against once set. === is used for equality checks.

// item-view.tsx
import {
  render
  useDirty,
  Box,
  Text,
  Input,
} from '@square/web-addons-dashboard/react';
import React, { useCallback } from 'react';

export default render(() => {
  const { value, setValue, isDirty, setInitialValue } = useDirty<string>('');
  const onReset = useCallback(() => {
    // Reset the initial value to compare dirty against
    setInitialValue();
  }, [setInitialValue]);
  const onChange = useCallback(
    (value: string) => {
      setValue(value);
    },
    [setValue],
  );

  return(
    <Box>
      <Text>{isDirty}</Text>
      <Input
        value={value}
        type="string"
        required={true}
        onChange={onChange}
      ></Input>
    </Box>
  );
});

Examples

Blade and Modal Lifecycle

Rendering of blades and modals must escape the render context from which they are requested to be shown. Therefore a method has been provided on the GlobalAPI to show these placements. You will not find a component for these in the SDK. Lets run through an example lifecyle flow for showing a square.dashboard.blade placement. The same steps apply to the square.dashboard.modal placement.

The Add-on view extracts the show properties from the GlobalAPI included on its placement API. It then executes the show on button click passing some contextual properties along to the view to be rendered in the blade sandbox.

// customer-view.tsx
import {
  render
  useCustomerViewApi,
  useCustomerViewCustomer,
  Button
} from '@square/web-addons-dashboard/react';
import React from 'react';

export default render(() => {
  const { blade } = useCustomerViewApi();
  const customer = { id: 1 };

  return (
    <Button
      data-testid="show-blade"
      rank="secondary"
      onClick={() => {
        blade.show({
          props: customer,
        });
      }}
    >
      Show Blade
    </Button>
  );
});

Upon execution of the show mthod, the manifest is parsed for a view which has a square.dashboard.blade placement. The entryPoint is then extracted and loaded into a blade sandbox. All view placement keys are unique in the manifest.

The Add-on blade view extracts the properties supplied by the calling context. Note these values are not subscribable and will not update if changed by the calling context once the blade renders.

//blade.tsx
import { useBladeApi, render, Label } from '@square/web-addons-dashboard/react';
import React from 'react';

export default render(() => {
  const { props } = useBladeApi();
  return (
    <Label>
      {props.id} // renders 1
    </Label>
  );
});