Your URLs inevitably encode some sort of state, even if that state is simply "what page am I on". Out of the box, JSF got it right. All forms are posted back to the original View ID. But this doesn't tell the whole story because the View ID is not the Request URL and we lose state that is encoded in request parameters or RESTful URL schemes like /app/widgets/300/edit.

We can fix this fairly easily.

All we need to do is post back to the original Request URL instead of the View ID and we're done.

Here is a custom ViewHandler which does exactly that.