isomorphic-router-demo
isomorphic-router-demo copied to clipboard
A starter project to help you quickly set up an isomorphic webapp using React Router 4 and react-router-config
isomorphic-router-demo
To try out the app:
$ git clone https://github.com/xiaoyunyang/isomorphic-router-demo.git
$ cd isomorphic-router-demo
$ npm install
$ npm start
Go to http://localhost:3000 to get the code up and running
To learn more about this repo and what an isomorphic app: https://hackernoon.com/get-an-isomorphic-web-app-up-and-running-in-5-minutes-72da028c15dd
Motivation
This is a demo project to show you how to set up an isomorphic webapp using React Router 4 and react-router-config.
The app has a few pages:
- The Home page, which includes two sets of dynamic loading to server APIs to grab JSON data to be displayed on the page. This is achieved via isomorphic-fetch. One isomorphic-fetch returns the same JSON data every time and the other one returns a different JSON each time.
- The About page
- The NotFound page, which gets rendered anytime an unrecognized route is requested.
App Building Blocks
├── build
| └── main.bundle.js <=== A2
├── client
| └── main.js <=== B2
├── iso-middleware
| └── renderRoute.js <=== A4
├── package.json
├── .babelrc
├── .env
├── server
| ├── run.js
| └── server.js <=== A5
├── shared
| ├── App.js <=== B3
| ├── components
| | ├── About.js
| | ├── HTML.js <=== A3
| | ├── TopNav.js <=== B4
| | ├── Home.js
| | ├── Main.js <=== B5
| | └── NotFound.js
| └── routes.js <=== B6
└── webpack.config.js <=== A1, B1
Notes:
-
Server Render: A
- A1.
webpack.config.jscreates/build/main.bundle.jswhen the app is first built. - A2.
main.bundle.jsis used inHTML.js - A3.
HTML.jsis a React component used to generate the template HTML that the server sends to the browser when it gets an HTTPGETrequest from the browser (called the initial load). - A4.
renderRoute.jsrenders a static version of theApp(using theStaticRouteras a container) into the HTML template inHTML.js, converts everything to string using React's server rendering support, then send the final string version of the HTML to send for HTTP GET request. - A5.
server.jsresponds to the initial load request by gettingrenderRoutesto respond with an HTML.
- A1.
-
Client Render: B
- B1.
webpack.config.jsidentifies the entry point for the client app asmain.js - B2.
main.jsrenders a SPA version of the app usingBrowserRouteras container forApp. - B3.
Appincludes aTopNavand aMain. - B4.
TopNavcontains React RouterLinkcomponents, which navigates to the route upon click. - B5.
Maincontains a React RouterSwitchcomponent, which switches between theHome,About, andNotFoundcomponents depending on the route. - B6.
routes.jsdetermines the mapping between routes and theHome,About, andNotFoundcomponents.
- B1.
Isomorphic Webapp Concepts
- Initial Load: The HTML that server gets an initial request via a HTTP GET request. The server grabs what it needs to render the HTML, such as data from a database or static assets like images, then sends HTML to the browser.
- SPA mode: After initial load, the page should immediately enters Single Page Application (SPA) mode. In SPA mode:
- The app can support quick navigation between pages without refreshing the page, and if done right, can even work offline.
- Updates are initiated by events, such as mouse clicks or scroll from the user.
- Additional data can by grabbed by talking to an API. The server serves up data, usually as JSON, to an api endpoint (RESTful API or GraphQL).
Resources
Here are some repos and tutorials that helped me figure out how to set up the project:
- technology-ebay-de/universal-react-router4
- zacfukuda/universal-app-react-router
- React Router training on server rendering
- isomorphic-dev-js
- EmileCantin's blog
- Elyse Kolker Gordon's Slides: SlideShare / GoogleDoc
- Going Isomorphic With React Presentation
TODOs
- [X] Add
isomorphic-fetchexample to show app grabbing data from an api endpoint while in SPA mode. - [ ] Add example for redirect with message to the router
- [ ] Add webpack HMR and React Hot Loader
- [ ] Add data preloading example
- [ ] Add redux example