> Note: > This is a legacy API. Use the latest version of [`Contextual Save Bar`](/docs/api/app-bridge-library/apis/contextual-save-bar) instead. Display the contextual save bar to indicate that a form on the current page contains unsaved information, or when the users is in the process of creating a new object, such as a product or customer. The contextual save bar provides save and discard buttons to a user. A close-up image of a Shopify admin contextual save bar. The contextual save bar displays the message: Unsaved changes. It features two buttons: a white button with the label Discard, and a green button with the label Save. The following are ways to use the contextual save bar: 1. [Plain JavaScript](#plain-javascript) 2. [React hook](#usecontextualsavebar-hook) 3. [React component](#contextualsavebar-component) ## Plain JavaScript ### Example code Import the `createApp` function from `@shopify/app-bridge` and the `ContextualSaveBar` from `@shopify/app-bridge/actions`. Then use the `createApp` function to create an app. > Note > In the following example, `config` is a valid App Bridge configuration object. Learn more about [configuring App Bridge](/docs/api/app-bridge/previous-versions/app-bridge-from-npm/app-setup#initialize-shopify-app-bridge-in-your-app). ```js import createApp from '@shopify/app-bridge'; import {ContextualSaveBar} from '@shopify/app-bridge/actions'; const app = createApp(config); ``` ### Create and show Create a contextual save bar instance with some initial options. Then dispatch a `SHOW` action to display it on the page. ```js const contextualSaveBar = ContextualSaveBar.create(app, { saveAction: { disabled: false, loading: false, }, discardAction: { disabled: false, loading: false, discardConfirmationModal: true, }, }); contextualSaveBar.dispatch(ContextualSaveBar.Action.SHOW); ``` > Note > Navigation actions ([Redirect](/docs/api/app-bridge/previous-versions/actions/navigation/redirect-navigate) and [History](/docs/api/app-bridge/previous-versions/actions/navigation/history)) on Shopify Admin are also blocked while the contextual save bar is visible. > If your app contains a title bar, you will not be able to make any updates to the title bar buttons while a contextual save bar is being shown. In addition, all title bar buttons will be disabled automatically while the contextual save bar is displayed. The disabled state of buttons inside the title bar are automatically reset to their previous states when the contextual save bar is hidden. To learn more about the title bar, see [Title Bar action](/docs/api/app-bridge/previous-versions/actions/titlebar). ### Update options You can modify the options at any time using the `set` method. If the contextual save bar is visible, the UI will update immediately. ```js contextualSaveBar.set({discardAction: {loading: true}}); ``` ### Hide Dispatch a `HIDE` action when you want to hide the contextual save bar. ```js contextualSaveBar.dispatch(ContextualSaveBar.Action.HIDE); ``` ### Subscribe to Discard and Save Subscribe to the contextual save bar actions (`ContextualSaveBar.Action.DISCARD` and `ContextualSaveBar.Action.SAVE`) in order to do something when a user clicks the Save or Discard button. The `subscribe` method returns a function that you can call to unsubscribe from the action. To hide the contextual save bar, dispatch a `ContextualSaveBar.Action.HIDE` action in the subscribe callback. ```js const discardUnsubscribe = contextualSaveBar.subscribe( ContextualSaveBar.Action.DISCARD, function() { // Hide the contextual save bar contextualSaveBar.dispatch(ContextualSaveBar.Action.HIDE); // Do something with the discard action } ); const saveUnsubscribe = contextualSaveBar.subscribe( ContextualSaveBar.Action.SAVE, function() { // Optionally, show a loading spinner while the save action is in progress contextualSaveBar.set({saveAction: {loading: true}}); await doSaveAction(); // Hide the contextual save bar contextualSaveBar.dispatch(ContextualSaveBar.Action.HIDE); } ); // Unsubscribe discardUnsubscribe(); saveUnsubscribe(); ``` ### Unsubscribe Call the `unsubscribe` method to remove all current subscriptions on the contextual save bar. ```js contextualSaveBar.subscribe(ContextualSaveBar.Action.DISCARD, function () { // Do something with the discard action // Hide the contextual save bar contextualSaveBar.dispatch(ContextualSaveBar.Action.HIDE); }); contextualSaveBar.subscribe(ContextualSaveBar.Action.SAVE, function () { // Do something with the save action // Hide the contextual save bar contextualSaveBar.dispatch(ContextualSaveBar.Action.HIDE); }); // Unsubscribe contextualSaveBar.unsubscribe(); ``` > Note > Navigation actions ([Redirect](/docs/api/app-bridge/previous-versions/actions/navigation/redirect-navigate) and [History](/docs/api/app-bridge/previous-versions/actions/navigation/history)) on Shopify Admin are blocked while the contextual save bar is visible. To dispatch navigation actions, first dispatch `ContextualSaveBar.Action.HIDE`. ## React ### `useContextualSaveBar` hook `useContextualSaveBar` is a hook that accepts no arguments and returns an object with the following methods and objects: - `show: ({fullWidth?: boolean; leaveConfirmationDisable?: boolean}) => void;` - `hide: () => void;` - `saveAction: { setOptions: (options: SaveActionOptions) => void };` - `discardAction: { setOptions: (options: DiscardActionOptions) => void };` #### Example Code > Note > When using the App Bridge React library, you need to wrap all of your App Bridge React code inside of a single App Bridge [`Provider`](/docs/api/app-bridge/previous-versions/app-bridge-from-npm/using-react#provider). ```jsx import {Provider, useContextualSaveBar} from '@shopify/app-bridge-react'; function MyApp { // Setup appBridgeConfig... const {show, hide, saveAction, discardAction} = useContextualSaveBar(); saveAction.setOptions({ disabled: false, loading: false, onAction: () => console.log('On save action') }); discardAction.setOptions({ disabled: false, loading: false, discardConfirmationModal: true, onAction: () => console.log('On discard action') }); return ( ); } ``` #### API The `useContextualSaveBar` hook does not accept any props. The following are the APIs for the methods and objects that the hook returns: `show` |Name|Type|Description|Required| |---|---|---|---| |fullWidth|`boolean`|Whether the contextual save bar should fill the entire screen width |No| |leaveConfirmationDisable|`boolean`|Whether to show a confirmation modal after the user navigates away from the page|No| `hide` No arguments. ##### saveAction.setOptions Refer to [`SaveActionOptions`](#saveactionoptions). ##### discardAction.setOptions Refer to [`DiscardActionOptions`](#discardactionoptions). ### `ContextualSaveBar` component `ContextualSaveBar` is a component that accepts [props](#props). #### Example Code > Note > When using the App Bridge React library, you need to wrap all of your App Bridge React code inside of a single App Bridge [`Provider`](/docs/api/app-bridge/previous-versions/app-bridge-from-npm/using-react#provider). ```jsx import {Provider, ContextualSaveBar} from '@shopify/app-bridge-react'; function MyApp { // Setup appBridgeConfig... const saveAction = { disabled: false, loading: false, onAction: () => console.log('On save action') } const discardAction = { disabled: false, loading: false, discardConfirmationModal: true, onAction: () => console.log('On discard action') } return ( ); } ``` ### Props The `ContextualSaveBar` component accepts the following props: |Name|Type|Description|Required| |---|---|---|---| |saveAction|[`SaveActionOptions`](#saveactionoptions)|Options to customize save behaviour |No| |discardAction|[`DiscardActionOptions`](#discardactionoptions)|Options to customize discard behaviour|No| |fullWidth|`boolean`|Whether the contextual save bar should fill the entire screen width |No| |leaveConfirmationDisable|`boolean`|Whether to show a confirmation modal after the user navigates away from the page|No| |visible|`boolean`|Whether the contextual save bar appears on the screen|No| ### Shared APIs Both the `ContextualSaveBar` component and the `useContextualSaveBar` hook use the following types: #### `SaveActionOptions` |Name|Type|Description|Required| |---|---|---|---| |disabled|`boolean`|Whether the contextual save bar button is in a disabled state |No| |loading|`boolean`|Whether the contextual save bar button is in a loading state |No| |onAction|`() => void`| A callback fired when the user presses the save button |No| #### `DiscardActionOptions` |Name|Type|Description|Required| |---|---|---|---| |disabled|`boolean`|Whether the contextual discard bar button is in a disabled state |No| |loading|`boolean`|Whether the contextual discard bar button is in a loading state |No| |onAction|`() => void`| A callback fired when the user presses the discard button |No| |discardConfirmationModal|`boolean`|Whether to show a confirmation modal after the user clicks the Discard button of the contextual save bar |No|