# `Cinder.UrlSync`
[🔗](https://github.com/sevenseacat/cinder/blob/v0.18.0/lib/cinder/url_sync.ex#L5)

Keeps a collection's filters, sorting, search and page in the URL.

## Usage

1. Add `use Cinder.UrlSync` to your LiveView, after `use MyAppWeb, :live_view`
   (or `use Phoenix.LiveView`).
2. Pass `url_state={@url_state}` to your collection.

## Example

    defmodule MyAppWeb.UsersLive do
      use MyAppWeb, :live_view
      use Cinder.UrlSync

      def mount(_params, _session, socket) do
        {:ok, assign(socket, :current_user, get_current_user())}
      end

      def render(assigns) do
        ~H"""
        <Cinder.collection
          resource={MyApp.User}
          actor={@current_user}
          url_state={@url_state}
        >
          <:col :let={user} field="name" filter sort>{user.name}</:col>
          <:col :let={user} field="email" filter>{user.email}</:col>
        </Cinder.collection>
        """
      end
    end

Your LiveView can still have its own `handle_params/3` and `handle_info/2`: they run as
usual, and `@url_state` is already assigned when `handle_params/3` runs.

## Custom URL Parameters

The URL sync helper automatically preserves custom (non-collection) query parameters
while managing collection state. The collection component knows which parameters it manages
(filters, page, sort, page_size, search) and will preserve any other parameters
in the URL.

For example:

    # URL with custom params and collection state
    /users?tab=overview&view=grid&name=john&page=2

    # When "name" filter is cleared, custom params are preserved
    /users?tab=overview&view=grid&page=2

    # When navigating to a different page, custom params remain
    /users?tab=overview&view=grid&page=3

You can use any parameter names for custom state without worrying about conflicts
with collection parameters. The collection automatically tracks which filter fields it manages
and will only remove those when filters are cleared.

# `__using__`
*macro* 

Adds URL sync to a LiveView. It must come after `use Phoenix.LiveView` (or
`use MyAppWeb, :live_view`).

Adds `on_mount Cinder.UrlSync`, and a `handle_params/3` that does nothing, which your
LiveView can replace with its own.

# `build_url`

Builds a new URL by merging collection state with existing query parameters.

This function is extracted for testing purposes. It builds the URL that
would be pushed by `update_url/3`.

## Parameters

- `encoded_state` - Map of URL parameters from collection state
- `current_uri` - Optional current URI string to use for path resolution
- `socket` - Optional socket for fallback path resolution

## Returns

A string representing the new URL with merged query parameters

# `extract_collection_state`

The same as `extract_url_state/1`.

# `extract_url_state`

Decodes URL parameters into a collection's state: its `:filters`, `:current_page`,
`:sort_by`, `:page_size`, `:search_term`, and keyset `:after` and `:before`.

Without the collection's columns, filters are only partly decoded and the sort isn't
checked. This isn't what `url_state` takes: `use Cinder.UrlSync` builds that for you.

# `get_url_state`

Returns `@url_state` from a socket's assigns, or `nil`:

    Cinder.UrlSync.get_url_state(socket.assigns)

It contains:
- filters: Raw URL parameters for proper filter decoding
- current_page: Current page number
- sort_by: Sort configuration
- uri: Current URI

# `handle_params`

Assigns `@url_state` from the URL parameters. `use Cinder.UrlSync` calls it for you, before
your own `handle_params/3`, so you don't need to.

## Parameters

- `params` - URL parameters from `handle_params/3`
- `uri` - Current URI from `handle_params/3` (optional but recommended)
- `socket` - The LiveView socket

## Returns

Updated socket with `:url_state` assign containing:
- `filters` - Raw URL parameters for proper filter decoding
- `current_page` - Current page number
- `sort_by` - Sort configuration
- `uri` - Current URI for URL generation

# `on_mount`

Assigns `@url_state` from the URL, and updates the URL when a collection's state changes.
`use Cinder.UrlSync` adds it. On its own (`on_mount Cinder.UrlSync`, or on a
`live_session`), the LiveView needs a `handle_params/3` if any other hook halts without one.

# `update_url`

Updates the LiveView socket with new URL parameters.

This function preserves the current path and updates only the query parameters
with the new collection state.

## Parameters

- `socket` - The LiveView socket
- `encoded_state` - Map of URL parameters from collection state
- `current_uri` - Optional current URI string to use for path resolution

## Returns

Updated socket with URL changed via `push_patch/2`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
