Skip to content

Commit

Permalink
Extend frontend docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Deraen committed Jan 28, 2025
1 parent dfc5a4e commit 4eb29d3
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 14 deletions.
7 changes: 6 additions & 1 deletion doc/frontend/basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ history events
- Stateful wrapper for easy use of history integration
- Optional [controller extension](./controllers.md)

You likely won't use `reitit.frontend` directly in your apps and instead you
will use the API documented in the browser integration docs, which wraps these
lower level functions.

## Core functions

`reitit.frontend` provides some useful functions wrapping core functions:
Expand All @@ -23,7 +27,8 @@ enabled.

`match-by-name` and `match-by-name!` with optional `path-paramers` and
logging errors to `console.warn` instead of throwing errors to prevent
React breaking due to errors.
React breaking due to errors. These can also [encode query-parameters](./coercion.md)
using schema from match data.

## Next

Expand Down
5 changes: 4 additions & 1 deletion doc/frontend/browser.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ There are also secondary functions following HTML5 History API:
`push-state` to navigate to new route adding entry to the history and
`replace-state` to change route without leaving previous entry in browser history.

See [coercion notes](./coercion.md) to see how frontend route parameters
can be decoded and encoded.

## Fragment router

Fragment is simple integration which stores the current route in URL fragment,
Expand Down Expand Up @@ -62,7 +65,7 @@ event handler for page change events.

## History manipulation

Reitit doesn't include functions to manipulate the history stack, i.e.
Reitit doesn't include functions to manipulate the history stack, i.e.,
go back or forwards, but calling History API functions directly should work:

```
Expand Down
59 changes: 59 additions & 0 deletions doc/frontend/coercion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Frontend coercion

The Reitit frontend leverages [coercion](../coercion/coercion.md) for path,
query, and fragment parameters. The coercion uses the input schema defined
in the match data under `:parameters`.

## Behavior of Coercion

1. **Route Matching**
When matching a route from a path, the resulting match will include the
coerced values (if coercion is enabled) under `:parameters`. If coercion is
disabled, the parsed string values are stored in the same location.
The original un-coerced values are always available under `:path-params`,
`:query-params`, and `:fragment` (a single string).

2. **Creating Links and Navigating**
When generating a URL (`href`) or navigating (`push-state`, `replace-state`, `navigate`)
to a route, coercion can be
used to encode query-parameter values into strings. This happens before
Reitit performs basic URL encoding on the values. This feature is
especially useful for handling the encoding of specific types, such as
keywords or dates, into strings.

3. **Updating current query parameters**
When using `set-query` to modify current query parameters, Reitit frontend
first tries to find a match for the current path so the match can be used to
first decode query parameters and then to encode them. If the current path
doesn't match the routing tree, `set-query` keeps all the query parameter
values as strings.

## Notes

- **Value Encoding Support**: Only Malli supports value encoding.
- **Limitations**: Path parameters and fragment values are not encoded using
the match schema.

## Example

```cljs
(def router (r/router ["/"
["" ::frontpage]
["bar"
{:name ::bar
:coercion rcm/coercion
:parameters {:query [:map
[:q {:optional true}
[:keyword
{:decode/string (fn [s] (keyword (subs s 2)))
:encode/string (fn [k] (str "__" (name k)))}]]]}}]]))

(rfe/href ::bar {} {:q :hello})
;; Result "/bar?q=__hello", the :q value is first encoded

(rfe/push-state ::bar {} {:q :world})
;; Result "/bar?q=__world"
;; The current match will contain both the original value and parsed & decoded parameters:
;; {:query-params {:q "__world"}
;; :parameters {:query {:q :world}}}
```
28 changes: 16 additions & 12 deletions modules/reitit-frontend/src/reitit/frontend/history.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,10 @@
The URL is formatted using Reitit frontend history handler, so using it with
anchor element href will correctly trigger route change event.
Note: currently collections in query parameters are encoded as field-value
pairs separated by &, i.e. \"?a=1&a=2\", if you want to encode them
differently, convert the collections to strings first."
By default currently collections in query parameters are encoded as field-value
pairs separated by &, i.e. \"?a=1&a=2\". To encode them differently, you can
either use Malli coercion to encode values, or just turn the values to strings
before calling the function."
([history name]
(href history name nil))
([history name path-params]
Expand All @@ -208,9 +209,10 @@
Will also trigger on-navigate callback on Reitit frontend History handler.
Note: currently collections in query-parameters are encoded as field-value
pairs separated by &, i.e. \"?a=1&a=2\", if you want to encode them
differently, convert the collections to strings first.
By default currently collections in query parameters are encoded as field-value
pairs separated by &, i.e. \"?a=1&a=2\". To encode them differently, you can
either use Malli coercion to encode values, or just turn the values to strings
before calling the function.
See also:
https://developer.mozilla.org/en-US/docs/Web/API/History/pushState"
Expand All @@ -236,9 +238,10 @@
Will also trigger on-navigate callback on Reitit frontend History handler.
Note: currently collections in query-parameters are encoded as field-value
pairs separated by &, i.e. \"?a=1&a=2\", if you want to encode them
differently, convert the collections to strings first.
By default currently collections in query parameters are encoded as field-value
pairs separated by &, i.e. \"?a=1&a=2\". To encode them differently, you can
either use Malli coercion to encode values, or just turn the values to strings
before calling the function.
See also:
https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState"
Expand All @@ -264,9 +267,10 @@
Will also trigger on-navigate callback on Reitit frontend History handler.
Note: currently collections in query-parameters are encoded as field-value
pairs separated by &, i.e. \"?a=1&a=2\", if you want to encode them
differently, convert the collections to strings first.
By default currently collections in query parameters are encoded as field-value
pairs separated by &, i.e. \"?a=1&a=2\". To encode them differently, you can
either use Malli coercion to encode values, or just turn the values to strings
before calling the function.
See also:
https://developer.mozilla.org/en-US/docs/Web/API/History/pushState
Expand Down

0 comments on commit 4eb29d3

Please sign in to comment.