Skip to content

2026-10-02 · WekeyLab AI · Planning work archive

Why did my filters reset when I returned to the list?

Opening a course detail should not mean starting the search again. Separate applied filters from reading position, then connect missing items, failed queries and new tabs to a specification and an engineering/QA handoff.

Split the request before deciding where to save filters

Imagine someone browsing Design courses in the North district on page 2. They open Poster Making, read the details, then return to page 1 for every district. Saving a filter value is only part of this fictional problem. The applied conditions, the place they were reading and the results currently on screen must agree.

A single last-used value sounds sufficient until another tab starts browsing cooking classes. One shared value can overwrite the Design visit. It also cannot reproduce the conditions from a shared address. Separate committed public filters, unapplied edits and the position within this particular list visit before choosing storage.

Use that distinction as the first planning deliverable. Each category needs a lifetime and a fallback when its state is missing. Otherwise engineering may preserve a control while the actual results reset, leaving a screen that looks correct but behaves incorrectly.

What should survive a return?

Example contract for a public course catalogue.

What should survive a return?
StateExampleStorage and scope
Applied conditionsDesign / North / start date / page 2URL; sharing, reload and history traversal
Unapplied editsA different district before ApplyCurrent screen; reset from the traversed entry
Reading positionPoster Making link and relative positionPer-list-visit context; return to that visit only
Result dataCourses, order and countRevalidate; historical results are not promised

Share the conditions, keep position with the visit

MDN distinguishes adding an entry with pushState from replacing one with replaceState. URLSearchParams handles query-string values. These are browser primitives, not a product policy. Planning still has to decide which action deserves an entry.

For this example, category, district, sort and page are public applied conditions in the URL. Personal queries and authentication information are excluded. Associate the remembered course and position with that specific list visit, not a global last position. A new tab can then open the conditions without needing the original tab’s position.

The same address does not promise an identical list forever. Courses close or disappear. The commitment is current results under the same conditions. A service that needs a historical view must separately preserve its observation time and result set; that is a different requirement.

Compare storage options

This case is about browsing current public results.

Compare storage options
OptionWhat it offersDecision
One global last-used stateSimple continuation on one deviceReject: tab interference and weak sharing
Put every state in the URLShare filters and positionReject: draft edits and visit position do not need sharing
Public filters in URL; position per visitSeparate sharing from returningChoose; no promise of a historical result set

Specify how many history entries Apply creates

Adding an entry for every edit makes Back retrace unfinished filter work. Here, controls edit a draft until Apply is pressed. Applying a changed category, district or sort resets to page 1 and adds one entry. Applying a state identical to the current committed state adds none.

Pagination preserves filters and sort. Back and Forward read existing entries and must not add another. Restore both committed and draft controls from the entry URL before querying. An unfinished draft must not leak into an older list visit.

Defaults are all categories, all districts, start-date order and page 1. An unknown district, a negative page or a duplicate condition key uses the documented default for that field. Explain the correction and replace the current entry. A previously valid page that disappears because results shrink is handled separately.

Actions, conditions and history

Editing a draft is not navigation.

Actions, conditions and history
ActionConditions and screenHistory
Edit a filterDraft only; committed results remainNo change
Apply changed filters or sortPage 1; query committed conditionsAdd one entry
Apply identical conditionsKeep current stateNo additional entry
Change pageKeep filters and sortAdd one entry
Back or ForwardSynchronize controls and results from that entryNo additional entry
Malformed URL valueUse field default and explainReplace current entry

A return does not make an old response current

Before opening details, associate the list address, course identity, position and input method with that visit. Use Back only when the immediate predecessor is a verified same-tab list visit. Otherwise navigate to a validated list address. With no return context, offer the default catalogue link, not blind navigation to a previous external website.

Query current results after returning. Comparing filters alone cannot distinguish an older retry for the same conditions. Check both the current visit and newest request sequence before applying a response. Cancelling a previous request is useful, but does not replace the final eligibility check.

Restore position after current results render. If the course remains on that page, reveal it; for keyboard entry, focus its link. If absent, return to the results heading and explain the changed list. Cancel a delayed automatic move if the reader has already started another interaction. Give restoration one owner so browser restoration and application code do not compete.

Check before applying a result

Discard an old response, then check the current request when it arrives.

Check before applying a resultDiscard an old response, then check the current request when it arrives.Current visit andnewest request bothmatch?YesRender results for thecurrent conditionsNoDiscard old response; awaitthe current requestAfter render, return toitem/heading unless anotherinteraction has started
Read the flow
  1. Current visit and newest request both match?
    • Yes: Render results for the current conditions → After render, return to item/heading unless another interaction has started
    • No: Discard old response; await the current request → Check again

Include the cases where the old item is gone

Page 2 may survive while the remembered course moves elsewhere. Searching every page automatically can delay return while results keep changing. This case looks only within the current page. If the item is absent, retain the filters and use the results heading instead of resetting the catalogue.

A failed query keeps the URL and applied conditions and offers Retry. Hide previous results so they cannot look like the new query’s output. A successful zero-result response is a different state. If the requested page exceeds the current last page, retain filters and sort, move to the last valid page and explain why. Zero matches uses page 1. Replace the current entry for this correction.

The buttons below compare fixed example messages; they do not query a course server. Opening a shared list address in a new tab starts at the results heading for those conditions. It must not inherit another person’s scroll or focus.

Compare return messages by situation

Fictional courses and responses; these are fixed message examples.

Open the example
Back at the course

Design / North / start date / page 2. Poster Making remains in current results. Reveal it and, for keyboard entry, focus its link.

Ask AI to find missing transitions before storage code

A request for filter-saving code can jump straight to implementation. First give the entry route, the moment conditions become committed, the return target and the failure policy. Ask for missing transitions within that scope.

If a proposal saves only the last scroll position, ask whose position it is after another tab, a deleted item or a late response. If it puts everything in the URL, ask it to separate shareable public conditions from visit-specific context. Adopt a suggestion only after comparing its behavior against the decision table and expected results.

The prompt below is an unexecuted example. A follow-up can add a retry under identical conditions, direct detail entry and another filter action during loading. For every new condition, identify the corresponding transition in the specification and acceptance case in QA. A longer answer is not evidence that these links are correct.

Example prompt: We are designing a public course catalogue. A reader views Design / North / start-date order / page 2, opens details and returns. Applied filters go in the URL; return position belongs to the specific list visit. Find missing conditions for draft versus applied filters, Back, new tabs, item deletion and retries with identical conditions. For each, provide the screen message, state change, engineering handoff and QA expectation. Exclude personal queries and infinite scrolling.

Connect the planning decision to screens and responses

The planning document records the restoration commitment and exclusions. The specification maps Apply, loading, failure and return to messages and actions. Naming a storage mechanism alone leaves room for implementations with identical screens and contradictory Back behavior.

Agree on sorting with engineering. Use a stable course-identity order to break equal start dates. That prevents ties from being arbitrarily reordered, but additions and deletions can still change pagination. The response contract should expose the applied conditions, count and page range; it must not be described as preserving the old order.

W3C’s focus-order guidance emphasizes meaningful, operable keyboard navigation. Returning to a surviving course link or the results heading is the policy selected here with that principle in mind, not a specific target required by WCAG. Check visible focus and the next Tab destination in the actual interface.

Who leaves which record?

Name the document and the behavior it must settle.

Who leaves which record?
OwnerRecordCheck against
PlanningRestoration scope, alternatives and exceptionsDefaults, sharing, direct entry and deletion
EngineeringURL validation, history, request sequence and sorting contractApplied conditions match current response
DesignLoading, failure, changed-list messages and focusDesktop, mobile and keyboard flow
QAInput, transition sequence, expected and observed resultsTwelve cases below and actual responses
OperationsClosing, deletion and shrinking-result fixturesOld results are not mistaken for current ones

One successful Back click is not the whole check

Record the URL, applied-filter display and actual results together. Restored controls with results from another query are a failure. The table below is an acceptance plan for implementation, not a claim that a real course service has already passed integration testing.

Repeat the same sequence on desktop and mobile, including keyboard entry into details. Slow the query and apply another filter while waiting. Old results and delayed focus must not take over. Reproducible handoff needs the same conditions and failure policy across input methods.

Return-to-list acceptance cases

Attach observed results, screens and request evidence to each row.

Return-to-list acceptance cases
Input or transitionExpected result
Edit without ApplyCommitted conditions/results remain; no entry
Apply changed category, district or sortPage 1; one new entry
Apply identical committed conditionsNo duplicate entry
Page 2 → details → BackRestore conditions; validate results; return to surviving item
Back → ForwardRestore each entry without creating another
Open URL in another tabCurrent results for same conditions; start at heading
Direct detail entry → catalogue linkDefault list if no context; no external detour
Remembered item deleted or moved to another pageKeep conditions; results heading and change notice
Failed query → RetryKeep conditions; hide old results; new request sequence
Old response with identical filters arrives lateDiscard unless current visit and newest request match
Page range shrinks or becomes emptyLast valid page or page-1 empty state; replace entry
Keyboard return; another action during loadingVisible link/heading focus; cancel delayed movement

Adapt the list commitment before reusing the handoff

This handoff assumes a public catalogue with numbered pages. Infinite scrolling, personalized recommendations or an audit view need a different restoration contract. In particular, do not apply a current-results policy to a screen that must preserve transactions or work records as observed at a specific time.

Before implementation, planning, engineering and design should walk the same fixture. Agree where conditions commit, what survives failure and where a missing item sends the reader. Update the specification and QA together. Different defaults in different documents are unfinished handoff.

For first release, prioritize disagreement between conditions, URL and response. Block release, fix the transition and repeat the same sequence. After deployment, review closing and deletion cases with operations. Any newly discovered exception should update the decision table, message and QA case together.

Return-to-list engineering and QA handoff

Public catalogue example. Adapt the scope and defaults to your service.

Public course catalogue — filter state and return handoff
Scope: public category, district, sort and numbered pages. Excludes personal queries, login, personalized recommendations and infinite scrolling.
Fixture: Design / North / start-date order / page 2 / 20 per page. Open Poster Making in the same tab, then return.
Storage: applied public filters belong in the URL. Unapplied edits stay in the screen. Store item identity, position and input method against that particular list visit, never in a shared URL. Ignore absent or mismatched return context.
Apply: applying filters or sort resets to page 1 and adds one history entry. Applying the same committed state adds none. Pagination preserves filters and sort. Defaults: all categories, all districts, start-date order, page 1.
History traversal: restore the entry URL into both applied and draft controls, then query without adding an entry. Normalize malformed values to documented defaults, explain the change and replace the current entry. Duplicate filter keys take the corresponding default.
Return action: use Back only for a verified same-tab immediate list predecessor. Otherwise navigate to a validated list URL. With no list context, offer the default catalogue link. Never use an arbitrary external return URL or blind history.back().
Responses: apply only a response matching the current visit and newest request sequence. A retry for the same conditions has a new sequence. On failure retain conditions and URL, hide previous results and offer Retry. Zero matches is a successful empty result.
Position: after rendering current results, reveal the remembered item if it still belongs to that page. For keyboard entry, focus its link. If missing or without return context, use the results heading. Cancel delayed automatic movement if the reader has started another interaction. Browser and app restoration must have one owner.
Shrunken page range: retain filters and sort, use the last valid page and replace the current entry. For zero matches use page 1 and the empty state. Explain the change; do not scan every page to chase the old item.
Sharing: a new tab opens current results for those conditions from the results heading. Old order, counts and scroll are not guaranteed. Break equal start dates with a stable course-identity order.
Ownership: planning decides restoration and exceptions; engineering handles URL validation, history, request sequences and a single restoration owner; design covers state messages and focus; QA uses the 12 acceptance cases; operations checks deletion, closing and reduced-page cases.
Release: align the decision sheet, screen transitions and wording, API sort/count contract and QA inputs/expected results. Block release if URL, applied controls and the current response disagree.
Verification boundary: a design example based on public browser references and fictional conditions, not a completed integration test of a course service.

Download the engineering and QA handoff

Sources and example conditions

This is a fictional public course catalogue design. Browser references support capabilities and accessibility principles; return behavior, defaults and failure handling are choices for this case. This is not a live course-service integration test or a user-outcome report. AI prompts are unexecuted examples. English and Chinese localize the same Korean case.

MDN — Working with the History API

MDN — URLSearchParams

W3C — Understanding SC 2.4.3 Focus Order