Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Extracted page-server rendering into a separate async (returns Pr…
…omise) function `render`
  • Loading branch information
catamphetamine committed Jul 22, 2016
1 parent 2eeedc7 commit ad4c0e6
Show file tree
Hide file tree
Showing 13 changed files with 404 additions and 240 deletions.
5 changes: 5 additions & 0 deletions HISTORY.md
@@ -1,3 +1,8 @@
4.0.16 / 22.07.2016
===================

* Extracted `page-server` rendering into a separate `async` (returns Promise) function `render` (see readme for arguments and return values)

4.0.15 / 22.07.2016
===================

Expand Down
143 changes: 109 additions & 34 deletions README.md
Expand Up @@ -38,7 +38,7 @@ export default
Start webpage rendering server

```javascript
import webpage_server from 'react-isomorphic-render/page-server'
import webpage_server from 'react-isomorphic-render/server'
import settings from './react-isomorphic-render'

// Create webpage rendering server
Expand All @@ -55,8 +55,8 @@ const server = webpage_server

// URLs of javascript and CSS files
// which will be insterted into the <head/> element of the resulting Html webpage
// (as <script src="..."/> and <link rel="style" href="..."/>)
//
// as <script src="..."/> and <link rel="style" href="..."/> respectively.
// (can be a function)
assets:
{
javascript: '/assets/application.js',
Expand Down Expand Up @@ -218,6 +218,72 @@ app.use(function(request, response)
})
```

## Without proxying

To use `react-isomorphic-render` without proxying there are two options

* Supply custom Koa `middleware` array option to webpage server
* Use `render` function manually:

```js
import { render } from 'react-isomorphic-render/server'

try
{
// Returns a Promise.
//
// status - HTTP response status
// content - rendered HTML document (markup)
// redirect - redirection URL (in case of HTTP redirect)
//
const { status, content, redirect } = await render
({
// Takes the same parameters as webpage server
application: { host, port },
assets,

// Plus two extra parameters:

// Original HTTP request, which is used for
// getting URL, cloning cookies, and inside `preload`.
request,

// Preferred locale (e.g. 'ru-RU').
// Can be obtained from 'Accept-Language' HTTP header.
preferred_locale,

// The rest options are the same as for webpage server
// and are all optional.
preload(),
localize(),
disable_server_side_rendering, // true/false
head,
body,
body_start,
body_end,
style
},
// The second `settings` parameter is the same as for webpage server
settings)

if (redirect)
{
return request.redirect(redirect)
}

if (content)
{
response.status(status || 200)
response.send(content)
}
}
catch (error)
{
response.status(500)
response.send('Internal server error')
}
```

## HTTP response status code

To set custom HTTP response status code for a specific route set the `status` property of that `<Route/>`.
Expand Down Expand Up @@ -376,6 +442,8 @@ this.props.dispatch(goto('/items/1?color=red'))
// Handles errors occurring inside `@preload()`.
// For example, if `@preload()` throws a `new Error("Unauthorized")`,
// then a redirect to "/unauthorized" page can be made here.
// If this error handler is defined then it must handle
// all errors it gets (or just re`throw` them).
on_preload_error: (error, { url, redirect }) => redirect(`/error?url=${encode(url)}&error=${error.code}`)

// (optional)
Expand Down Expand Up @@ -442,7 +510,9 @@ this.props.dispatch(goto('/items/1?color=red'))

// (optional)
// Is called when an error happens on the server side
// (can redirect to special "500 Error" pages)
// (can redirect to special "500 Error" pages).
// If this error handler is defined then it must handle
// all errors it gets (or just re`throw` them).
on_error: (error, { url, redirect }) => redirect(`/error?url=${encode(url)}&error=${error.code}`)

// (optional)
Expand All @@ -452,36 +522,41 @@ this.props.dispatch(goto('/items/1?color=red'))
middleware: [...]

// (optional)
// Returns React element an array of React elements
// which will be inserted into server rendered webpage's <head/>
// (in case of an array use `key`s to prevent React warning)
head: (url) => React element or an array of React elements

// (optional)
// Allows for wrapping React page component with arbitrary elements
// (or doing whatever else can be done with a React element).
// Returns either a React element or an array of React elements
// which will be inserted into server rendered webpage's <body/>
body: react_page_element => react_page_element

// (optional)
// Returns React element or an array of React elements.
// Allows adding arbitrary React elements to the start of the <body/>
// (use `key`s to prevent React warning when returning an array of React elements)
body_start: (url) => React element or an array of React elements

// (optional)
// Returns React element or an array of React elements.
// Allows adding arbitrary React elements to the end of the <body/>
// (use `key`s to prevent React warning when returning an array of React elements)
body_end: (url) => React element or an array of React elements

// (optional)
// (is used only in development mode, for "flash of unstyled content")
// This function returns CSS text which will be inserted
// into server rendered webpage's <head/> <style/> tag.
// If you're using Webpack then the CSS text is the result of a require() call.
style: () => 'body { background: white }'
// HTML code injection
html:
{
// (optional)
// Returns React element an array of React elements
// which will be inserted into server rendered webpage's <head/>
// (in case of an array use `key`s to prevent React warning)
head: (url) => React element or an array of React elements

// (optional)
// Allows for wrapping React page component with arbitrary elements
// (or doing whatever else can be done with a React element).
// Returns either a React element or an array of React elements
// which will be inserted into server rendered webpage's <body/>
body: react_page_element => react_page_element

// (optional)
// Returns React element or an array of React elements.
// Allows adding arbitrary React elements to the start of the <body/>
// (use `key`s to prevent React warning when returning an array of React elements)
body_start: (url) => React element or an array of React elements

// (optional)
// Returns React element or an array of React elements.
// Allows adding arbitrary React elements to the end of the <body/>
// (use `key`s to prevent React warning when returning an array of React elements)
body_end: (url) => React element or an array of React elements

// (optional)
// (is used only in development mode, for "flash of unstyled content")
// This function returns CSS text which will be inserted
// into server rendered webpage's <head/> <style/> tag.
// If you're using Webpack then the CSS text is the result of a require() call.
style: () => 'body { background: white }'
}

// (optional)
// Preloads data before performing page rendering.
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "react-isomorphic-render",
"version": "4.0.15",
"version": "4.0.16",
"description": "Isomorphic rendering with React, Redux, React-router and Redux-router. Includes support for Webpack",
"main": "index.umd.js",
"//jsnext:main": "index.es6.js",
Expand Down
3 changes: 2 additions & 1 deletion page-server.js
@@ -1,2 +1,3 @@
// just an npm package helper
module.exports = require('./build/page-server/web server')
// (for backwards compatibility; use `react-isomorphic-render/server` instead)
module.exports = require('./server')
9 changes: 9 additions & 0 deletions server.js
@@ -0,0 +1,9 @@
// npm package helper

var web_server = require('./build/page-server/web server')

exports = module.exports = web_server

exports.render = require('./build/page-server/render')

exports['default'] = web_server
2 changes: 1 addition & 1 deletion source/page-server/html.js
Expand Up @@ -37,7 +37,7 @@ export default class Html extends Component
// (but server-side rendering is always enabled so this "if" condition may be removed)
let content_markup = this.props.children ? ReactDOMServer.renderToString(this.props.children) : ''

let content_element = <div id="react" dangerouslySetInnerHTML={{__html: content_markup}}/>
let content_element = <div id="react" dangerouslySetInnerHTML={{ __html: content_markup }}/>

if (body)
{
Expand Down

0 comments on commit ad4c0e6

Please sign in to comment.