Retaining state with the router in a single page application

In the last post, I mentioned the importance of “guiding principles” when starting a new project and how including them from the beginning is much easier than applying them later. One example of this in Cushion is when I decided to treat routing like a view renderer instead of a navigation system with state. I can click around the app and it’ll show the correct sections, but there are plenty of areas where refreshing the page completely loses state—like, the date range of the schedule view or the client of a drafted invoice. In both of these cases, I should’ve relied on query parameters rather than passing these values through the app’s store. With query params, Cushion would retain state upon refresh, but instead, users not only lose their place, but they also can’t revisit it using their browser history.

Now that I’m exploring a modern Cushion, this is another opportunity to correct a misstep from years ago. By establishing a guiding principle that “refreshing the page should retain state”, I know to factor routing into every view. If a section has any sort of date dropdown, I’ll make sure that the date is represented as a query param:


When creating an invoice for a certain client, I’ll make sure Cushion navigates to the invoice route with the client’s ID in the URL:


This all sounds obvious, but when you’re excitedly building something new, these seemingly small details can easily slip through the cracks. That’s okay, though. You won’t build everything perfectly the first time—that’s why apps have versions.