Skip to content

createLocationState: option to drop state written with an older shape (version / validate) #994

Closed

Description

@ivogt

Problem

A createLocationState key is derived from the file path and export name (src/vite/plugins/expose-ids/handler-transform.ts:48-53), so it stays the same across deploys. The read is an unchecked cast (src/browser/react/location-state.ts:20).

A tab that stays open across a deploy that changed the state's shape restores the old value typed as the new one. Code then reads missing or renamed fields, or a changed structure, with no type error and no runtime check. History entries survive reloads and back/forward indefinitely, so long-lived tabs hit this after an ordinary release.

Seen on 0.18.0.

Proposal

An option on createLocationState that lets a definition reject state it can't trust, for example:

export const GridState = createLocationState<GridSnapshot>({ version: 2 });
// stored as { v: 2, value }; a different or missing version reads as undefined

export const GridState = createLocationState<GridSnapshot>({
  validate: (value): value is GridSnapshot => isGridSnapshot(value),
});
// run on read; a failing value reads as undefined

version is cheap and covers deliberate shape changes. validate also covers state written by other code under the same key. Either keeps the typed read honest. An entry that fails the check reads as undefined, which is the same result as no state.

Activity

  1. added 6 commits that reference this issue on Oct 2, 2026
    97ac52c
    b10306d
    d564cf4
    b27247e
    b3f999b
    1bc1889
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions