Skip to content

[Review Changes]: T2 - URL-based tag filter encoding + filter-aware initial story selection #34252

@valentinpalkovic

Description

@valentinpalkovic

Overview

Replace localStorage persistence for tag filters with URL-based state. Tag filter state is encoded in a tags URL parameter; status filter state is encoded in a separate statuses URL parameter (implemented in T7). Fix the existing bug where initial story selection ignores active tag filters when navigating to Storybook without a story path.

Scope

URL encoding (bidirectional sync):

  • On startup, read the tags URL parameter from the current URL. Split on semicolons; entries prefixed with ! go to excludedTagFilters, all others to includedTagFilters. Map only known built-in URL tags ($docs, $play, $test) to internal _-prefixed equivalents (e.g., $docs_docs); leave all other $... tags untouched
  • When any tag filter is toggled (via addTagFilters, removeTagFilters, resetTagFilters, setAllTagFilters), serialize the current filter state into a single tags URL parameter and update the URL. Tags are separated by semicolons. Built-in tags (internal _ prefix) are serialized with $ prefix (e.g., _docs$docs). Excluded tags are prefixed with ! (e.g., ?tags=$docs;a11y;!experimental)
  • Remove { persistence: 'permanent' } from all tag filter mutations in file:code/core/src/manager-api/modules/stories.ts — filter state is URL-only, no localStorage
  • Remove the startup code that reads includedTagFilters / excludedTagFilters from persistedState (localStorage); replace with URL-based initialization

Filter-aware initial story selection (bug fix):

  • Fix selectFirstStory() in file:code/core/src/manager-api/modules/stories.ts to use filteredIndex when filters are active, falling back to index when no filters are active. If filteredIndex is empty, suppress navigation
  • Fix the STORY_SPECIFIED handler: when isCanvasRoute is true and active filters exist, check whether the emitted storyId is present in filteredIndex. If not, navigate to the first story in filteredIndex instead. If filteredIndex is empty, suppress navigation entirely

Out of scope

  • The statuses URL parameter (T7)
  • Status-based filtering in the TagsFilterPanel (T7)
  • Any server-side changes (T1, T3)

Acceptance Criteria

  • Navigating to ?tags=play shows only stories tagged play in the sidebar
  • Navigating to ?tags=a11y;!experimental shows stories tagged a11y but not experimental
  • Unknown custom tags that start with $ are preserved as-is (not rewritten to _...)
  • Toggling a filter in the UI updates the URL immediately with semicolon-separated tags and $ prefix for built-in tags
  • Refreshing the page restores the same filter state from the URL
  • No tag filter state is written to or read from localStorage
  • Navigating to http://localhost:6006/?tags=play (no story path) selects the first story that passes the play filter, not the first story in the full index
  • If filteredIndex is empty on load, no story is selected and no navigation occurs

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions