package virtual_dom

  1. Overview
  2. Docs
Legend:
Library
Module
Module type
Parameter
Class
Class type

A quick overview of HTML5-History.

Primitives ---------- The primitives the browser provides to you are:

  • A stack of "history entries", which are tuples (state, uri) (strictly speaking they're three-tuples, but MDN says the "title" is completely ignored)
  • A function pushState that adds a new item to the stack with the given (state, uri)
  • A function replaceState that replaces the current top of stack with (state, uri)
  • A way of getting the current state and URI, particularly useful on initial page load.
  • An event you can listen to, popState, which fires whenever the user uses the browser's back/forwards button to move between two history states that were created by the same "page".

When using pushState or replaceState, the string in the address bar immediately changes to be uri without a page navigation/load (the URI must be of the same origin as the current URI).

MDN says the "state" can be "anything that can be serialised" (with some size limit, see push_or_replace); here we bin-prot your OCaml value and store the string (along with its bin-shape), so you needn't worry about that.

See more here: https://developer.mozilla.org/en-US/docs/Web/API/History.

Note that these primitives allow you to:

1. add an entry to the history stack (with a URI and/or state blob inside it), without causing a page load 2. handle the back button without a page load happening 3. change the string in the address bar without causing a page load; in fact without the addition of a new entry on the history stack if you wish 4. change the state blob inside the current history stack entry without adding a new entry or changing the string in the address bar

For an example of why you might want to do (4), have a look at the comment by History_state below ("you may like to put more information in your History_state.t ...").

module type Payload = sig ... end

We let you store a "payload" in each of the history entries. This works by bin-protting your value, and storing it alongside the bin-shape hash. When a history state is popped, we deserialise it only if the shape matches; otherwise you get None.

type _ t
val init_exn : ?log_s:(Core.Sexp.t -> unit) -> (module Payload with type t = 'p) -> 'p t

You can only call one of the "init" functions (here or in Opinionated), and moreover only once; this module is inherantly global.

module Entry : sig ... end
val popstate_bus : 'p t -> ('p Entry.t -> unit, Core.read) Bus.t
val current : 'p t -> 'p Entry.t

When calling push or replace, you can replace the uri by passing the optional argument uri; if ommitted it will be unchanged.

Note that the uri you pass here can be relative, and it will be resolved relative to the current uri. However, the uri you get back out of an _ Entry.t is _not_ relative; you won't necessarily get out the string you put in. I recommend you construct a uri with at most path and query in it.

These functions will raise in the case of uri syntax errors. The _browser_ may throw an exception if it doesn't like your uri or state, for example if the uri is not of the same origin, or the state is excessively large (multiple megabytes in Chrome, 640k in Firefox).

val push_or_replace : 'p t -> [ `Push | `Replace ] -> ?uri:Uri.t -> 'p -> unit
val push : 'p t -> ?uri:Uri.t -> 'p -> unit
val replace : 'p t -> ?uri:Uri.t -> 'p -> unit
module Opinionated : sig ... end

This module provides a more opinionated way to use html5-history; it's a thin wrapper over the above.