Skip to content

New withUrlParamsSync extension for URL-state synchronization #272

@yannickglt

Description

@yannickglt

I've created a withUrlParamsSync extension for NgRx Signal Store that automatically synchronizes selected state properties with URL parameters (query params or route params). It works bidirectionally: state changes update the URL, and URL changes update the state.

Why?

  • Users can share/bookmark URLs with filters, sorting, pagination preserved
  • Direct navigation to specific application states
  • No need to manually sync state ↔ URL in every component

Example

export const appRoutes: Route[] = [{
  path: 'visibility',
  data: { urlParamsSyncKey: 'todo-list' },
  loadComponent: () => ,
];



export const TodoListStore = signalStore(
  { providedIn: 'root' },
  withState(initialState),
  withUrlParamsSync<TodoListState>({
    key: 'todo-list', // Must match route.data['urlParamsSyncKey']
    select: (state) => ({
      'filters.search': state.filters.search,
      sortBy: state.sortBy,
      sortOrder: state.sortOrder,
    }),
    queryParamsKey: {
      'filters.search': 'search',
      sortBy: 'sort_by',
    },
    defaultValues: {
      'filters.search': null,
    },
    syncType: 'queryParams', // or 'routeParameters'
  }),
)

When filters.search changes, the URL updates to ?search=.... When the URL changes (e.g., user navigates back), the state updates automatically.

Features

  • ✅ Bidirectional sync (state ↔ URL)
  • ✅ Supports query params and route params
  • ✅ Nested objects via dot notation (filters.search)
  • ✅ Custom serialization/deserialization
  • ✅ Default value filtering (keeps URLs clean)
  • ✅ Key mapping (state key → URL param name)
  • ✅ Only syncs when target route is active

Implementation

The code is production-ready and unit tested. We use if in production for a month.
I think it can be useful to share and your repository (I use on my own) sounds the good place to host it.

If you're interested, I can create a PR with the implementation.

Let me know if you'd like me to proceed and if there are rules to follow 🙂

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions