> 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.
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|