Every dashboard eventually needs the same three things. A search box, a few filters, and pagination once the list gets long. The version I used to build kept all of that in useState, which meant losing your filters the moment you refreshed the page or shared a link with someone else.

Keeping this state in the URL instead fixed both problems at once. Here is the setup.

1. Why URL Search Params, Not useState

State in useState disappears on refresh and cannot be shared or bookmarked. The same filtered, paginated view living in the URL means a refresh keeps your place, a shared link shows the same filtered results to whoever opens it, and the browser's back button actually works the way people expect.

/dashboard/orders?search=invoice&status=pending&page=2