You can have it in one place without using background sync.

Our application uses classical "foreground update" paradigm, but each API call automatically shows an error to the user and returns him/her to the same place where error originated to fix the input and/or retry. As a bonus, we also automatically show progress indicator for any HTTP request that takes more than 1s (which is rare).

This is as simple as:

    await context.api.explorer.rename(
        {
            objectKey,
            name
        }
    );

    // objectKey: ApiTypes.ObjectKey
    // name: string
The above initiates an HTTP request:

- If that request succeeds, you know that the new name has been durably committed to the database.

- If it fails because the new name is not unique, the user sees the error, and can then enter a different name before retrying. The key is that the UI context is preserved during API failure, so everything the user had entered is still on the screen.

- If it takes more than 1s, the user sees a progress indicator which he/she can click to cancel the operation. This also returns him/her to the original UI.

The magic is in the `rename` itself - it was auto-generated from our back-end API such that it wires into our error reporting and progress UI.