Is it possible to detect reenter or back button in POS UI extension?

I use the Navigation API in a POS UI extension (2025-10).

navigation.navigate('/ScreenTwo', { state: { foo: 'bar' })

Now I’m looking for a way to detect when the user leaves /ScreenTwo and the screen that opened this screen becomes visible again.

Following ways are possible to leave /ScreenTwo

  • using back button on the top left
  • navigation.back()

How to detect that a screen becomes “visible” again?

Also I don’t see how to listen for the back button. Maybe it’s necessary to prevent this event. E.g. to enforce the user to save the changes.

Hey @Jens_Simon - thanks for flagging this. At the moment, this is expected behaviour and a limitation of our POS UI extension framework, but we are aware of the issue and enabling screen state detection/better navigation is on our radar (can’t guarantee an exact turnaround time on this though). Just wanted to reach out to confirm I’ve passed along your comments as well.

Please let me know if we can assist with anything else on our end here. :slight_smile:

1 Like

Hi @Alan_G,

thanks for your statement.

I tried to describe in Navigation API (2025-10): data flow between screens how I currently try to handle screens in my current project.

I try to summarize it a bit.

modal.js - acts as router

function Extension() {
  const { url } = navigation.currentEntry

  if (url === '/TransferDetail') {
    return <TransferDetail />
  }

  if (url === '/TransferDetailItem') {
    return <TransferDetailItem />
  }

  return <TransferSelection />
}

Pass a callback function to the state object of navigation.navigate().
The screen which uses this state uses the callback to notify about a change.

const state = navigation.currentEntry.getState()
const {
  calllback,
} = state

callback()
const [timestamp, setTimestamp] = useState(Date.now()) // to force re-render on line item transfer update

useEffect(() => {
  foo()
}, [timestamp])

return <>
  {lineItems.map((lineItem) => (
    <s-clickable for={lineItem.id} onClick={() => {
      navigation.navigate('/TransferDetailItem', {
        state: {
          callback: () => {
            setTimestamp(Date.now())
          },
        },
      })
    )}>
      <s-text>{lineItem.id}</s-text>
    </s-clickable>
  })}
</>

I’m aware of the limitations (Navigation API).
I know that non-serializable data of type function is passed to the navigation state.

But it works!
And I don’t see what can happen doing so.
I understand that function isn’t serializable. But I don’t know the impact of this fact.

And: I really try to avoid usage of complex state management like Redux.

So what are my risks?

Hey @Jens_Simon, thanks for sharing your current implementation and the breakdown there, I appreciate it.

We don’t officially support this since the main risk here is that navigation state is typically designed to be serializable so it can be persisted/restored. If the POS app is backgrounded or needs to restore state, functions won’t survive serialization, which could lead to crashes or unexpected behavior. Also, since this relies on undocumented behaviour, future updates to the Navigation API could break this approach without warning.

That said, if it’s working reliably in your testing and you’re comfortable with those risks, it’s up to you if you’d like to continue using the method. You might want to consider alternatives like storing shared data in a module that both screens can access, but I understand wanting to keep things simple. Let me know if you’d like to discuss any alternatives further or if there’s anything else I can help with! :slight_smile:

1 Like

Thanks @Alan_G, that is the missing part I hadn’t in mind.

If the POS app is backgrounded or needs to restore state, functions won’t survive serialization, which could lead to crashes or unexpected behavior.

Got it. And now I see the risks.

It probably doesn’t have a big impact for my extension. But I see the potential for some strange behaviour.

It’s not my intention to misuse an API.

I don’t want to use a navigation state to implement communication between screens.

But if it’s a way to work around a limitation of the API it could be acceptable. With risk in mind.

Hopefully only until a better solution is available.

For now it’s just a way to ensure that when going back to the previous screen the modifications from the closed screen will be displayed. Data already get persisted using Storage API.

The only thing I would need is a event handler that gets called when the screen gets focus again. Or something similar.

You might want to consider alternatives like storing shared data in a module that both screens can access, but I understand wanting to keep things simple.

That sounds interesting. But it isn’t exactly what I really need.

But… Will it survive POS app backgrounding? I guess it will…

Already mentioned before. I don’t want to introduce Redux (synonym for the whole state management solutions) too early.

But maybe it’s a good option.

Hey @Jens_Simon, happy to help with this. To answer your question there, a shared module won’t survive backgrounding either since it’s just in-memory. But since you’re already persisting data with Storage API, you should b e able to use the shared module as a lightweight notification mechanism to tell screens to re-read from storage. If the app backgrounds and restores, screens re-mount and can read fresh data from Storage on mount anyway.

A simple pub/sub or event emitter pattern would work well for this without needing anything as heavy as Redux. Should give you that “onFocus-like” behavior you’re after while keeping everything serializable. We wouldn’t be able to help with the specific code implementation of this (generally can only share info/troubleshooting directly related to our libraries/SDKs), but hopefully this give you some ideas on where to start!