The documentation page here: Save Bar links to the ui-save-bar page. However the “old” url: https://shopify.dev/docs/api/app-bridge-library/web-components/ui-save-bar just redirects back to https://shopify.dev/docs/api/app-home/apis/save-bar. Why was the page removed?
Hi @alessandro.tesoro, it may have been down temporarily.
Can you check if you’re able to visit it now?
The issue has not gone away.
https://shopify.dev/docs/api/app-bridge-library/web-components/ui-save-bar
is redirecting to the below it seems
https://shopify.dev/docs/api/app-home/apis/save-bar
Update: The reason why we’re now redirecting https://shopify.dev/docs/api/app-bridge-library/web-components/ui-save-bar to https://shopify.dev/docs/api/app-home/apis/save-bar is to encourage the use of the Save Bar API going forward. <ui-save-bar> is still supported, but we will be cleaning up remaining references to it to ensure the recommended approach to the save bar is followed instead.
But the documentation does not encourage the use of the Save Bar API. The whole documentation is a confusing mess.
If ui-save-bar is going to be deprecated, what is the best way to rewrite the “old way” to use the new pattern. I couldn’t find a way to add an ID to the data-save-bar so there is no way to programmatically show or hide the saveBar.
<ui-save-bar id="my-save-bar">
<button variant="primary" onclick={(e) => { e.currentTarget.setAttribute('loading', true); saveChanges(e) }}>Save</button>
<button onclick={(e) => resetChanges(e) }>Discard</button>
</ui-save-bar>
export function checkDirty() {
let newData = $state.snapshot(blocks_state);
let oldData = $state.snapshot(original_state);
let check = JSON.stringify(newData) == JSON.stringify(oldData);
if (!check) {
app_state.isDirty = true;
shopify?.saveBar.show("my-save-bar");
} else {
app_state.isDirty = false;
shopify?.saveBar.hide("my-save-bar");
}
return check;
}
Thank you
Is there any clear direction on how to handle programmatic interaction with the save bar? The “automatic” way doesn’t work for our use case because a) we have found it to be unreliable if the form can be updated in any way other than an input and b) we have to block navigation when the save bar is showing.
The documentation examples show the API being used without IDs. However, the method reference shows that an ID string should be passed in.
Also, if there is no longer an element in our app, how do we control things like loading and disabled state, button text, etc.?
We would like to know the “right” way to do things before we go and re-write this functionality (again).
Have you looked at these docs?
Thank you @Luke. Yes, that is the exact doc I am referencing. You’ll notice that there is no longer a <ui-save-bar> element in the examples.
Previous comments seem to indicate that this is intentional and that devs are being funnelled to this as the recommended approach.
But that leads me back to the questions I asked in my previous post.
As the example shows, you don’t need ui-save-bar, its already in there, you can just programmatically show/hide as required. Have you attempted to use the example provided on that link?
Thanks @Luke. Yes I have. I understand how to hide and show the save bar.
I’m trying to figure out how all the rest of the functionality fits into this (save actions, reset actions, disabled and loading state).
The <ui-save-bar> gave us a way to handle all of that declaratively.
This is less a question about how “the new way” works and more about how we should be moving forward. Is <ui-save-bar> still a legitimate way to work with the API? Or will we be forced off of it down the road?
Hi @Station_Team,
You would handle most actions on the form e.g.
<form
data-save-bar
onSubmit={handleFormSubmit}
onReset={handleFormReset}
>
<s-text-field
label="Test Input"
name="value"
disabled={isSaving}
/>
</form>
If you need programmatic control, you can still use shopify.saveBar.show(), shopify.saveBar.hide(), and shopify.saveBar.leaveConfirmation().
<ui-save-bar> is still a legitimate way to work with the API for now, but we encourage you to adopt the new approach using the data-save-bar attribute.
Thank you for the response @Paige-Shopify .
None of the examples in the link you included show programmatic control.
If programmatic control should be mixed with using <form data-save-bar> that is not clear from the examples in the documentation—specifically this doc: Save bar API .
If they shouldn’t be mixed, how should save/reset actions work. The example cited above shows handleSave and handleDiscard handlers, but they don’t seem to be connected to anything.
Perhaps you could provide a minimal example of how programmatic control should work, including save and discard actions. It looks like @app was asking for that as well.
For what it’s worth, it seems other people are also having issues: SaveBar API mismatch between docs and real code?
This is an important unresolved issue with the latest App Bridge and Polaris we’re supposed to be using now. There seems to be no documentation or clear way in plain vanilla JS to tell the automatic saveBar (the one that shows with a <form data-save-bar>) that the form submission wasn’t successful and the saveBar shouldn’t get dismissed. Even worse, there is no way currently to actually instantiate a saveBar manually. As the other post explains, there is some ID missing which doesn’t exist and can’t be specified. SaveBar API mismatch between docs and real code?
I’m the author of that post about SaveBar API mismatch, and I also have this issue with letting <form data-save-bar> know that if there was a validation error, save bar shouldn’t be dismissed.
So for me <form data-save-bar> approach doesn’t fully work and programmatic approach with shopify.saveBar.show() doesn’t work at all due to that missing ID issue.
I experimented with dispatchEvent(new Event('input', { bubbles: true })) approach on my app. For me, saveBar becomes visible only on first dispatch of such event, not on all the further dispatches. Quite a weird behavior…
I also tried to have an invisible input field that I can change the value of. And SaveBar does not react for the invisible inputs changes at all.
I have a different setup, not Vue. But thanks for the idea! I will do some more experiments ![]()
Just providing an update here. the Save Bar API docs have been updated to cover both implementation approaches (automatic and programmatic): Save bar API
If you’re running into issues with the programmatic approach specifically, let me know if those gaps are now covered or if anything is still missing. Thank you!
Hi Paige, thanks for the update.
The documentation for the Save Bar API still feels incomplete. There is no information on how to handle loading or disabled button states. There is also no documentation for triggering the discard confirmation modal through the API.
Many developers prefer the programmatic approach over the automatic form-based one for complex applications. It currently feels like this method is not fully supported or ready for production. Please consider adding these missing details to the documentation.