diff --git a/README.md b/README.md
index aa84781..12b3a60 100644
--- a/README.md
+++ b/README.md
@@ -225,6 +225,10 @@ Choo comes with a shared state object. This object can be mutated freely, and
is passed into the view functions whenever `'render'` is emitted. The state
object comes with a few properties set.
+When initializing the application, `window.initialState` is used to provision
+the initial state. This is especially useful when combined with server
+rendering. See [server rendering](#server-rendering) for more details.
+
### `state.events`
A mapping of Choo's built in events. It's recommended to extend this object
with your application's events. By defining your event names once and setting
@@ -295,8 +299,8 @@ To can navigate routes you can emit `'pushState'`, `'popState'` or
`'replaceState'`. See [#events](#events) for more details about these events.
## Server Rendering
-Choo was built with Node in mind. To render on the server call `.toString()` on
-your application.
+Choo was built with Node in mind. To render on the server call
+`.toString(route, [state])` on your application.
```js
var html = require('choo/html')
@@ -314,6 +318,25 @@ console.log(string)
// => '
Hello Node
'
```
+When starting an application in the browser, it's recommended to provide the
+same `state` object available as `window.initialState`. When the application is
+started, it'll be used to initialize the application state. The process of
+server rendering, and providing an initial state on the client to create the
+exact same document is also known as "rehydration".
+
+For security purposes, after `window.initialState` is used it is deleted from
+the `window` object.
+
+```html
+
+
+
+
+
+
+
+```
+
## Optimizations
Choo is reasonably fast out of the box. But sometimes you might hit a scenario
where a particular part of the UI slows down the application, and you want to
diff --git a/index.js b/index.js
index 86910aa..98fa41b 100644
--- a/index.js
+++ b/index.js
@@ -45,7 +45,16 @@ function Choo (opts) {
// properties that are part of the API
this.router = nanorouter({ curry: true })
this.emitter = nanobus('choo.emit')
- this.state = { events: this._events }
+
+ var events = { events: this._events }
+ if (this.hasWindow) {
+ this.state = window.initialState
+ ? xtend(window.initialState, events)
+ : events
+ delete window.initialState
+ } else {
+ this.state = events
+ }
// listen for title changes; available even when calling .toString()
if (this._hasWindow) this.state.title = document.title