SlideShare a Scribd company logo
REACTJS
UNIVERSAL JS APPLICATION WITH
05/2017
ABOUT ME
TRẦN TRỌNG THANH
▸ CTO & Co-founder NauStud.io
▸ 4 years with ActionScript, ex-Pycorian ;)
▸ 5 years with JavaScript
▸ Have worked with ReactJS, Angular 2, and learning VueJS
▸ SaigonJS FB group curator (bit.ly/saigonjs)
▸ Contact: Twitter/Facebook/Github /trongthanh
Nau is hiring! 😎❤☕
UNIVERSAL JS APPLICATION WITH REACTJS
A BRIEF HISTORY OF WEB APPS
▸ 1992 - Static HTML
▸ 1993 - Server side rendered HTML (CGI protocol)
▸ 1995 - LiveScript (a.k.a JavaScript) in Netscape Nav 2.0
▸ 1997 - Dynamic HTML, Internet Explorer 4
▸ 2005 - AJAX web apps
▸ 2010-ish - JS frameworks and Single page apps (SPA)
A BRIEF HISTORY OF WEB APPS
WHY SPA?
▸ Instant responses on the UI*
▸ No page refresh, allows page transitions
▸ Less overheads at server side
▸ App-like experience
▸ Foundation for Hybrid mobile apps
▸ More emphasis at Front End, enables back-end-less
A BRIEF HISTORY OF WEB APPS
THE ACHILLES’ HILL OF SPA (2015 A.D.)
😞 SEO
😞 First meaningful paint
😞 no-script
<!doctype html>
<html lang="en">
<head>
<title>My Awesome Single Page App</title>
<meta charset="utf-8">
<meta name="viewport" content="...">
<link rel="stylesheet" href="styles.min.css">
</head>
<body>
<div id="root" style="height: 100%"></div>
<script src="bundle.js"></script>
</body>
</html>
* Code sample from react-redux-starter-kit
A BRIEF HISTORY OF WEB APPS
OBVIOUS SOLUTION?
Render content HTML at server-side
MORE PROBLEMS?
😞 Duplicated rendering logic at server side
😞 Double work of template maintenance
😞 Flash of updated content
😞 All the relief of SPA for backend is gone
THE RISE OF 

UNIVERSAL JAVASCRIPT
APPLICATIONS
WHAT IS A
UNIVERSAL JS APPLICATION?
▸ Used to be called Isomorphic JS Applications
▸ There are portions of JS run on both client and server
(hence universal / isomorphic)
▸ Server-side rendered HTML
▸ Server-enabled History Push State
TRADITIONAL SPA WITH REDUX ARCHITECTURE
UNIVERSAL JS APP WITH REDUX ARCHITECTURE
CODE WALKTHROUGH
UNIVERSAL REACT APP
Based from a simple Universal Redux template
UNIVERSAL - CONTAINER COMPONENT
/*...*/
import { connect } from 'react-redux'
import { loadQuestionDetail } from 'actions/questions'
import { browserHistory } from 'react-router'
class Question extends Component {
static fetchData({ store, params, history }) {
let { id } = params
return store.dispatch(loadQuestionDetail({ id, history }))
}
componentDidMount() {
let { id } = this.props.params
this.props.loadQuestionDetail({ id, history: browserHistory })
}
render() {
return (<div> {/* stuff... */}</div>)
}
}
/*...*/
export default connect(mapStateToProps, { loadQuestionDetail })(Question)
SERVER - EXPRESS UNIVERSAL RENDERER MIDDLEWARE
import React from 'react'
import ReactDOMServer from 'react-dom/server'
import { useRouterHistory, RouterContext, match } from 'react-router'
import { createMemoryHistory, useQueries } from 'history'
import configureStore from 'store/configureStore'
import createRoutes from 'routes/index'
import { Provider } from 'react-redux'
server.get('*', (req, res, next) => {
let history = useRouterHistory(useQueries(createMemoryHistory))()
let store = configureStore()
let routes = createRoutes(history)
let location = history.createLocation(req.url)
match({ routes, location }, (error, redirectLocation, renderProps) => {
/* cont... */
})
}) //end server.get('*')
SERVER - EXPRESS UNIVERSAL RENDERER MIDDLEWARE
/*...*/
server.get('*', (req, res, next) => {
/* ... */
match({ routes, location }, (error, redirectLocation, renderProps) => {
/* handle error & redirectLocation... */
function getReduxPromise() { /*...*/ }
getReduxPromise().then(()=> {
let reduxState = escape(JSON.stringify(store.getState()))
let html = ReactDOMServer.renderToString(
<Provider store={store}>
{ <RouterContext {...renderProps}/> }
</Provider>
)
let metaHeader = Helmet.rewind()
// always render the index template
res.render('index', { metaHeader, html, reduxState, scriptSrcs, styleSrc })
})
.catch((err)=> {
Helmet.rewind()
next(err)
})
})
}) //end server.get('*')
SERVER - EXPRESS UNIVERSAL RENDERER MIDDLEWARE
function getReduxPromise() {
let { query, params } = renderProps
let comp = renderProps.components[renderProps.components.length - 1].WrappedComponent
let promise = comp.fetchData ?
comp.fetchData({ query, params, store, history }) :
Promise.resolve()
return promise
}
SERVER - EXPRESS UNIVERSAL RENDERER MIDDLEWARE
/*...*/
server.get('*', (req, res, next) => {
/* ... */
match({ routes, location }, (error, redirectLocation, renderProps) => {
/* handle error & redirectLocation... */
function getReduxPromise() { /*...*/ }
getReduxPromise().then(()=> {
let reduxState = escape(JSON.stringify(store.getState()))
let html = ReactDOMServer.renderToString(
<Provider store={store}>
{ <RouterContext {...renderProps}/> }
</Provider>
)
// always render the index template
res.render('index', { html, reduxState, /*...*/ })
})
.catch((err)=> {
next(err)
})
})
}) //end server.get('*')
SERVER - EXPRESS INDEX TEMPLATE
<!DOCTYPE html>
<html>
<head>
<%# metaHeader and stylesheet stuff, omit for clarity...%>
</head>
<body>
<div id="root"><%- html %></div>
<script type="text/javascript" charset="utf-8">
window.__REDUX_STATE__ = '<%= reduxState %>';
</script>
<% scriptSrcs.forEach(function(src){ %>
<script src="<%= src %>"></script>
<% }) %>
</body>
</html>
CLIENT - REACT APP.JS
/*...*/
import ReactDOM from 'react-dom'
import { browserHistory } from 'react-router'
import { Provider } from 'react-redux'
import createRoutes from 'routes/index'
import configureStore from 'store/configureStore'
let initialState = {}
if (window.__REDUX_STATE__) {
try {
initialState = JSON.parse(unescape(__REDUX_STATE__))
} catch (e) {
/*catch error*/
}
}
const store = configureStore(initialState)
ReactDOM.render((
<Provider store={store}>
{ createRoutes(browserHistory) }
</Provider>
), document.getElementById('root'))
DEMO
UNIVERSAL JS APPLICATION
WE HAVE SOLVED:
👍 SEO
👍 First meaningful paint
👍 no-script
👍 Code reuse
WAIT. 

THERE’S MORE
NEXT.JS
INTRODUCING
IN 2 MINUTES
LET’S CREATE A UNIVERSAL APP
Q&A
READ MORE
REFERENCES
▸ https://medium.com/@mjackson/universal-javascript-4761051b7ae9
▸ https://medium.com/node-security/the-most-common-xss-vulnerability-in-react-js-
applications-2bdffbcc1fa0
▸ https://github.com/mz026/universal-redux-template
▸ https://github.com/erikras/react-redux-universal-hot-example
▸ https://learnnextjs.com

More Related Content

PDF
«От экспериментов с инфраструктурой до внедрения в продакшен»​
PDF
React server side rendering performance
PPTX
Introduction to MongoDB
PDF
AngularJS Deep Dives (NYC GDG Apr 2013)
PDF
JS Chicago Meetup 2/23/16 - Redux & Routes
PDF
React.js in real world apps.
PDF
Integrating React.js Into a PHP Application
PDF
RDSDataSource: Мастер-класс по Dip
«От экспериментов с инфраструктурой до внедрения в продакшен»​
React server side rendering performance
Introduction to MongoDB
AngularJS Deep Dives (NYC GDG Apr 2013)
JS Chicago Meetup 2/23/16 - Redux & Routes
React.js in real world apps.
Integrating React.js Into a PHP Application
RDSDataSource: Мастер-класс по Dip

What's hot (20)

PPTX
Vue business first
PDF
Vue.js
PDF
Nuxt.JS Introdruction
PDF
Vue, vue router, vuex
PDF
Introduction to VueJS & Vuex
PDF
Redux Universal
PDF
Vue 淺談前端建置工具
PDF
Grails Launchpad - From Ground Zero to Orbit
PDF
Redux. From twitter hype to production
PDF
Workshop 22: React-Redux Middleware
PDF
Svelte JS introduction
PDF
Introduction to Node.js Platform
PDF
An Introduction To Testing In AngularJS Applications
PDF
Introduction to ReactJS
PPTX
Getting started with node.js
PDF
DevOps in the era of serverless computing - Alessandro Vozza - Codemotion Ams...
PDF
The Complementarity of React and Web Components
PPTX
Building a production ready meteor app
PDF
Breaking the Server-Client Divide with Node.js and React
PDF
VueJS: The Simple Revolution
Vue business first
Vue.js
Nuxt.JS Introdruction
Vue, vue router, vuex
Introduction to VueJS & Vuex
Redux Universal
Vue 淺談前端建置工具
Grails Launchpad - From Ground Zero to Orbit
Redux. From twitter hype to production
Workshop 22: React-Redux Middleware
Svelte JS introduction
Introduction to Node.js Platform
An Introduction To Testing In AngularJS Applications
Introduction to ReactJS
Getting started with node.js
DevOps in the era of serverless computing - Alessandro Vozza - Codemotion Ams...
The Complementarity of React and Web Components
Building a production ready meteor app
Breaking the Server-Client Divide with Node.js and React
VueJS: The Simple Revolution
Ad

Similar to Universal JS Applications with React (20)

PDF
Universal JavaScript
PDF
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
PDF
Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...
PDF
Workshop 27: Isomorphic web apps with ReactJS
PPTX
React js programming concept
PDF
Universal React apps in Next.js
PDF
Universal JavaScript - Frontend United Athens 2017
PDF
Building Universal Web Apps with React ForwardJS 2017
PPTX
intro to react| React: dynamic UIs, component-based, virtual DOM, JSX, effici...
PDF
Server rendering-talk
PDF
Review on React JS
PDF
Reactjs Basics
PPTX
React js
PPTX
React And Express Tutorial
PPTX
React JS Unleashing the Power of Front-End Development.pptx
PDF
The Road To Redux
PDF
Building Modern Web Applications using React and Redux
PDF
Performance and Scalability Art of Isomorphic React Applications
PDF
Using React, Redux and Saga with Lottoland APIs
PDF
Universal Applications
Universal JavaScript
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...
Workshop 27: Isomorphic web apps with ReactJS
React js programming concept
Universal React apps in Next.js
Universal JavaScript - Frontend United Athens 2017
Building Universal Web Apps with React ForwardJS 2017
intro to react| React: dynamic UIs, component-based, virtual DOM, JSX, effici...
Server rendering-talk
Review on React JS
Reactjs Basics
React js
React And Express Tutorial
React JS Unleashing the Power of Front-End Development.pptx
The Road To Redux
Building Modern Web Applications using React and Redux
Performance and Scalability Art of Isomorphic React Applications
Using React, Redux and Saga with Lottoland APIs
Universal Applications
Ad

Recently uploaded (20)

PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
Nekopoi APK 2025 free lastest update
PPTX
history of c programming in notes for students .pptx
PPTX
Reimagine Home Health with the Power of Agentic AI​
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
Understanding Forklifts - TECH EHS Solution
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
System and Network Administraation Chapter 3
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PPT
Introduction Database Management System for Course Database
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PPTX
L1 - Introduction to python Backend.pptx
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PDF
Digital Systems & Binary Numbers (comprehensive )
PPTX
Introduction to Artificial Intelligence
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Nekopoi APK 2025 free lastest update
history of c programming in notes for students .pptx
Reimagine Home Health with the Power of Agentic AI​
Design an Analysis of Algorithms I-SECS-1021-03
How to Migrate SBCGlobal Email to Yahoo Easily
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Understanding Forklifts - TECH EHS Solution
PTS Company Brochure 2025 (1).pdf.......
System and Network Administraation Chapter 3
Wondershare Filmora 15 Crack With Activation Key [2025
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Introduction Database Management System for Course Database
Adobe Illustrator 28.6 Crack My Vision of Vector Design
L1 - Introduction to python Backend.pptx
Navsoft: AI-Powered Business Solutions & Custom Software Development
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Digital Systems & Binary Numbers (comprehensive )
Introduction to Artificial Intelligence
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025

Universal JS Applications with React

  • 2. ABOUT ME TRẦN TRỌNG THANH ▸ CTO & Co-founder NauStud.io ▸ 4 years with ActionScript, ex-Pycorian ;) ▸ 5 years with JavaScript ▸ Have worked with ReactJS, Angular 2, and learning VueJS ▸ SaigonJS FB group curator (bit.ly/saigonjs) ▸ Contact: Twitter/Facebook/Github /trongthanh Nau is hiring! 😎❤☕
  • 3. UNIVERSAL JS APPLICATION WITH REACTJS A BRIEF HISTORY OF WEB APPS ▸ 1992 - Static HTML ▸ 1993 - Server side rendered HTML (CGI protocol) ▸ 1995 - LiveScript (a.k.a JavaScript) in Netscape Nav 2.0 ▸ 1997 - Dynamic HTML, Internet Explorer 4 ▸ 2005 - AJAX web apps ▸ 2010-ish - JS frameworks and Single page apps (SPA)
  • 4. A BRIEF HISTORY OF WEB APPS WHY SPA? ▸ Instant responses on the UI* ▸ No page refresh, allows page transitions ▸ Less overheads at server side ▸ App-like experience ▸ Foundation for Hybrid mobile apps ▸ More emphasis at Front End, enables back-end-less
  • 5. A BRIEF HISTORY OF WEB APPS THE ACHILLES’ HILL OF SPA (2015 A.D.) 😞 SEO 😞 First meaningful paint 😞 no-script <!doctype html> <html lang="en"> <head> <title>My Awesome Single Page App</title> <meta charset="utf-8"> <meta name="viewport" content="..."> <link rel="stylesheet" href="styles.min.css"> </head> <body> <div id="root" style="height: 100%"></div> <script src="bundle.js"></script> </body> </html> * Code sample from react-redux-starter-kit
  • 6. A BRIEF HISTORY OF WEB APPS OBVIOUS SOLUTION? Render content HTML at server-side MORE PROBLEMS? 😞 Duplicated rendering logic at server side 😞 Double work of template maintenance 😞 Flash of updated content 😞 All the relief of SPA for backend is gone
  • 7. THE RISE OF 
 UNIVERSAL JAVASCRIPT APPLICATIONS
  • 8. WHAT IS A UNIVERSAL JS APPLICATION? ▸ Used to be called Isomorphic JS Applications ▸ There are portions of JS run on both client and server (hence universal / isomorphic) ▸ Server-side rendered HTML ▸ Server-enabled History Push State
  • 9. TRADITIONAL SPA WITH REDUX ARCHITECTURE
  • 10. UNIVERSAL JS APP WITH REDUX ARCHITECTURE
  • 11. CODE WALKTHROUGH UNIVERSAL REACT APP Based from a simple Universal Redux template
  • 12. UNIVERSAL - CONTAINER COMPONENT /*...*/ import { connect } from 'react-redux' import { loadQuestionDetail } from 'actions/questions' import { browserHistory } from 'react-router' class Question extends Component { static fetchData({ store, params, history }) { let { id } = params return store.dispatch(loadQuestionDetail({ id, history })) } componentDidMount() { let { id } = this.props.params this.props.loadQuestionDetail({ id, history: browserHistory }) } render() { return (<div> {/* stuff... */}</div>) } } /*...*/ export default connect(mapStateToProps, { loadQuestionDetail })(Question)
  • 13. SERVER - EXPRESS UNIVERSAL RENDERER MIDDLEWARE import React from 'react' import ReactDOMServer from 'react-dom/server' import { useRouterHistory, RouterContext, match } from 'react-router' import { createMemoryHistory, useQueries } from 'history' import configureStore from 'store/configureStore' import createRoutes from 'routes/index' import { Provider } from 'react-redux' server.get('*', (req, res, next) => { let history = useRouterHistory(useQueries(createMemoryHistory))() let store = configureStore() let routes = createRoutes(history) let location = history.createLocation(req.url) match({ routes, location }, (error, redirectLocation, renderProps) => { /* cont... */ }) }) //end server.get('*')
  • 14. SERVER - EXPRESS UNIVERSAL RENDERER MIDDLEWARE /*...*/ server.get('*', (req, res, next) => { /* ... */ match({ routes, location }, (error, redirectLocation, renderProps) => { /* handle error & redirectLocation... */ function getReduxPromise() { /*...*/ } getReduxPromise().then(()=> { let reduxState = escape(JSON.stringify(store.getState())) let html = ReactDOMServer.renderToString( <Provider store={store}> { <RouterContext {...renderProps}/> } </Provider> ) let metaHeader = Helmet.rewind() // always render the index template res.render('index', { metaHeader, html, reduxState, scriptSrcs, styleSrc }) }) .catch((err)=> { Helmet.rewind() next(err) }) }) }) //end server.get('*')
  • 15. SERVER - EXPRESS UNIVERSAL RENDERER MIDDLEWARE function getReduxPromise() { let { query, params } = renderProps let comp = renderProps.components[renderProps.components.length - 1].WrappedComponent let promise = comp.fetchData ? comp.fetchData({ query, params, store, history }) : Promise.resolve() return promise }
  • 16. SERVER - EXPRESS UNIVERSAL RENDERER MIDDLEWARE /*...*/ server.get('*', (req, res, next) => { /* ... */ match({ routes, location }, (error, redirectLocation, renderProps) => { /* handle error & redirectLocation... */ function getReduxPromise() { /*...*/ } getReduxPromise().then(()=> { let reduxState = escape(JSON.stringify(store.getState())) let html = ReactDOMServer.renderToString( <Provider store={store}> { <RouterContext {...renderProps}/> } </Provider> ) // always render the index template res.render('index', { html, reduxState, /*...*/ }) }) .catch((err)=> { next(err) }) }) }) //end server.get('*')
  • 17. SERVER - EXPRESS INDEX TEMPLATE <!DOCTYPE html> <html> <head> <%# metaHeader and stylesheet stuff, omit for clarity...%> </head> <body> <div id="root"><%- html %></div> <script type="text/javascript" charset="utf-8"> window.__REDUX_STATE__ = '<%= reduxState %>'; </script> <% scriptSrcs.forEach(function(src){ %> <script src="<%= src %>"></script> <% }) %> </body> </html>
  • 18. CLIENT - REACT APP.JS /*...*/ import ReactDOM from 'react-dom' import { browserHistory } from 'react-router' import { Provider } from 'react-redux' import createRoutes from 'routes/index' import configureStore from 'store/configureStore' let initialState = {} if (window.__REDUX_STATE__) { try { initialState = JSON.parse(unescape(__REDUX_STATE__)) } catch (e) { /*catch error*/ } } const store = configureStore(initialState) ReactDOM.render(( <Provider store={store}> { createRoutes(browserHistory) } </Provider> ), document.getElementById('root'))
  • 19. DEMO
  • 20. UNIVERSAL JS APPLICATION WE HAVE SOLVED: 👍 SEO 👍 First meaningful paint 👍 no-script 👍 Code reuse
  • 23. IN 2 MINUTES LET’S CREATE A UNIVERSAL APP
  • 24. Q&A
  • 25. READ MORE REFERENCES ▸ https://medium.com/@mjackson/universal-javascript-4761051b7ae9 ▸ https://medium.com/node-security/the-most-common-xss-vulnerability-in-react-js- applications-2bdffbcc1fa0 ▸ https://github.com/mz026/universal-redux-template ▸ https://github.com/erikras/react-redux-universal-hot-example ▸ https://learnnextjs.com