Skip to content

Commit 507ec34

Browse files
committed
update <ServerRouter> docs
1 parent 76492a3 commit 507ec34

File tree

1 file changed

+44
-28
lines changed

1 file changed

+44
-28
lines changed

website/api/ServerRouter.md

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,79 @@
11
# `<ServerRouter>`
22

3-
Renders of your React Router app on the server and notifies you of
4-
redirects or `Miss` rendering.
3+
Server rendering is a bit more involved to properly handle `<Redirect>`
4+
and `<Miss>` in your app. Not only do you want to respond with the
5+
proper status code, but also, both function on the result of rendering
6+
so we have to sort of recreate `componentDidMount` for the server. For
7+
the exeptional case of not matching any patterns you'll use a two-pass
8+
render to render the `<Miss>` components.
59

6-
This is a very bare-bones example to illustrate the moving parts that
7-
involve `ServerRouter`, the rest is up to you.
10+
Here's an example that sends 301 for redirects and properly renders your
11+
app when no patterns match the url:
812

913
```js
14+
import { createServer } from 'http'
1015
import React from 'react'
1116
import { renderToString } from 'react-dom/server'
12-
import { createServer } from 'http'
17+
import { ServerRouter, createServerRenderContext } = 'react-router'
1318

1419
createServer((req, res) => {
1520

16-
// ServerRouter will callback to us if there is a redirect or Miss
17-
// while rendering
18-
let redirectLocation = null
19-
let missLocation = null
21+
// first create a context for <ServerRouter>, it's where we keep the
22+
// results of rendering for the second pass if necessary
23+
const context = createServerRenderContext()
2024

21-
const markup = renderToString(
25+
// render the first time
26+
let markup = renderToString(
2227
<ServerRouter
2328
location={req.url}
24-
onRedirect={location => redirectLocation}
25-
onMiss={location => missLocation}
29+
context={context}
2630
>
2731
<App/>
2832
</ServerRouter>
2933
)
3034

31-
if (redirectLocation) {
35+
// get the result
36+
const result = context.getResult()
37+
38+
// the result will tell you if it redirected, if so, we ignore
39+
// the markup and send a proper redirect.
40+
if (result.redirect) {
3241
res.writeHead(301, {
33-
Location: redirectLocation.pathname
42+
Location: result.redirect.pathname
3443
})
3544
res.end()
3645
} else {
37-
if (missLocation) {
46+
47+
// the result will tell you if there were any misses, if so
48+
// we can send a 404 and then do a second render pass with
49+
// the context to clue the <Miss> components into rendering
50+
// this time (on the client they know from componentDidMount)
51+
if (result.missed) {
3852
res.writeHead(404)
53+
markup = renderToString(
54+
<ServerRouter
55+
location={req.url}
56+
context={context}
57+
>
58+
<App/>
59+
</ServerRouter>
60+
)
3961
}
4062
res.write(markup)
4163
res.end()
4264
}
43-
44-
4565
}).listen(3000)
4666
```
4767

48-
## `location`
49-
50-
The location the server received, probably the string on `req.url` of a
51-
node server.
52-
53-
## `onRedirect`
68+
## `location: string`
5469

55-
Called when any Redirect happens while rendering your app. It calls back
56-
with the location of the redirect so you can send a proper 301 (or 302).
70+
The location the server received, probably `req.url` on a node server.
5771

58-
## `onMiss`
72+
## `context`
5973

60-
If any `Miss` components are rendered, this will be called with the
61-
location so you can send a proper 404 response with the content.
74+
An object returned from `createServerRenderContext`. It keeps the
75+
rendering result so you know which status code to send and if you need
76+
to perform a second pass render to render the `<Miss>` components in
77+
your app.
6278

6379
# `</ServerRouter>`

0 commit comments

Comments
 (0)