{"id":13475906,"url":"https://github.com/xkawi/react-universal-saga","last_synced_at":"2025-04-13T06:36:24.911Z","repository":{"id":57346988,"uuid":"62526539","full_name":"xkawi/react-universal-saga","owner":"xkawi","description":"Universal React Starter Kit ft. Redux Saga","archived":false,"fork":false,"pushed_at":"2018-05-02T14:17:21.000Z","size":151,"stargazers_count":186,"open_issues_count":2,"forks_count":33,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-24T07:57:08.452Z","etag":null,"topics":["react","redux","redux-devtools","redux-saga","webpack"],"latest_commit_sha":null,"homepage":"https://react-universal-saga.herokuapp.com","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xkawi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-07-04T02:43:54.000Z","updated_at":"2024-05-16T17:24:36.000Z","dependencies_parsed_at":"2022-09-17T22:50:34.707Z","dependency_job_id":null,"html_url":"https://github.com/xkawi/react-universal-saga","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xkawi%2Freact-universal-saga","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xkawi%2Freact-universal-saga/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xkawi%2Freact-universal-saga/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xkawi%2Freact-universal-saga/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xkawi","download_url":"https://codeload.github.com/xkawi/react-universal-saga/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248675301,"owners_count":21143763,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["react","redux","redux-devtools","redux-saga","webpack"],"created_at":"2024-07-31T16:01:24.612Z","updated_at":"2025-04-13T06:36:24.884Z","avatar_url":"https://github.com/xkawi.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Marks"],"sub_categories":["Boilerplate"],"readme":"\n# React Universal Saga\n\n[![React Universal Saga Version](https://img.shields.io/npm/v/react-universal-saga.svg?maxAge=2592000)](https://img.shields.io/npm/dm/react-universal-saga.svg?maxAge=2592000)\n[![Downloads](https://img.shields.io/npm/dm/react-universal-saga.svg?maxAge=2592000)](https://img.shields.io/npm/dm/react-universal-saga.svg?maxAge=2592000)\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/xkawi/react-universal-saga/master/LICENSE)\n\n\n[![Build Status](https://travis-ci.org/xkawi/react-universal-saga.svg?branch=master)](https://travis-ci.org/xkawi/react-universal-saga)\n[![Dependency Status](https://david-dm.org/xkawi/react-universal-saga.svg)](https://david-dm.org/xkawi/react-universal-saga)\n[![devDependency Status](https://david-dm.org/xkawi/react-universal-saga/dev-status.svg)](https://david-dm.org/xkawi/react-universal-saga#info=devDependencies)\n\n---\n\n## Getting Started\n\nUniversal React App Starter featuring Redux Saga. Heavily modified version of [React Redux Universal Hot Example](https://github.com/erikras/react-redux-universal-hot-example) combined with Redux Saga [real-world](https://github.com/yelouafi/redux-saga/tree/master/examples/real-world) example.\n\n`$ git clone https://github.com/xkawi/react-universal-saga`\n\n`$ cd react-universal-saga \u0026\u0026 npm install`\n\n`$ npm run dev` (run in development mode)\n\nLive Demo: [react-universal-saga.herokuapp.com](https://react-universal-saga.herokuapp.com)\n\nUPDATE: Checkout [react-universal-saga-modular](https://github.com/xkawi/react-universal-saga-modular) for a different structure of react-universal-saga that's more modular, scalable, and maintainable. :smile:\n\n## Features\n\n* [Universal](https://medium.com/@mjackson/universal-javascript-4761051b7ae9) rendering, with Client and Server Side Data Fetching\n* [React](https://github.com/facebook/react) - latest version `^15.4.2`\n* [Redux](https://github.com/rackt/redux)'s futuristic [Flux](https://facebook.github.io/react/blog/2014/05/06/flux.html) implementation\n* [Redux Saga](https://github.com/yelouafi/redux-saga) to handle all of your Side Effects logic in a central place\n* [React Router](https://github.com/ReactTraining/react-router/tree/v2.8.1)\n* [Express](http://expressjs.com)\n* [Babel](http://babeljs.io) for ES6 and ES7 magic\n* [Webpack](http://webpack.github.io) for bundling\n* [Webpack Dev Middleware](http://webpack.github.io/docs/webpack-dev-middleware.html)\n* [Webpack Hot Middleware](https://github.com/glenjamin/webpack-hot-middleware)\n* [Redux Dev Tools](https://github.com/gaearon/redux-devtools) for next generation DX (developer experience). Watch [Dan Abramov's talk](https://www.youtube.com/watch?v=xsSnOQynTHs).\n* [ESLint](http://eslint.org) to maintain a consistent code style\n* [redux-form](https://github.com/erikras/redux-form) to manage form state in Redux\n* [PostCSS](https://github.com/postcss/postcss-loader), [style-loader](https://github.com/webpack/style-loader), [sass-loader](https://github.com/jtangelder/sass-loader) and [less-loader](https://github.com/webpack/less-loader) to allow import of stylesheets in plain css, sass and less,\n* [bootstrap-loader](https://github.com/shakacode/bootstrap-loader) and [font-awesome-webpack](https://github.com/gowravshekar/font-awesome-webpack) to customize Bootstrap and FontAwesome\n* [react-helmet](https://github.com/nfl/react-helmet) to manage title and meta tag information on both server and client\n* [webpack-isomorphic-tools](https://github.com/halt-hammerzeit/webpack-isomorphic-tools) to allow require() work for statics both on client and server\n* [Jest](https://facebook.github.io/jest/) to allow writing unit tests for the project.\n* Refer to `package.json` for more details\n\n## New to React?\n\nCore Concepts to learn if you are new to ReactJS and this repo:\n\n- Dumb Components (Component) \n- Smart Component (Container)\n- Actions - define available action types\n- Reducers - given previous state and an action, create a new state\n- Sagas - manage or orchestrate event/action dispatching flow (called Side Effects)\n\n### Crash Course on React, Redux, and Redux Saga\n\n1. [Hands-on] [Get started with ReactJS](https://facebook.github.io/react/docs/tutorial.html)\n\n2. [Reading] [Thinking in React way](https://facebook.github.io/react/docs/thinking-in-react.html)\n\n3. [Reading] [Flux Pattern](https://code-cartoons.com/a-cartoon-guide-to-flux-6157355ab207#3c82)\n[(video)](https://www.youtube.com/watch?v=nYkdrAPrdcw\u0026feature=youtu.be)\n\n4. [Hand-on] [Flux](https://facebook.github.io/flux/docs/todo-list.html)\n\n5. [Reading] [Why someone created a tool called Redux](https://code-cartoons.com/hot-reloading-and-time-travel-debugging-what-are-they-3c8ed2812f35)\n\n6. [Reading] [More about Redux](https://code-cartoons.com/a-cartoon-intro-to-redux-3afb775501a6)\n\n7. [Hands-on] [Getting started with Redux](https://egghead.io/series/getting-started-with-redux)\n\n8. [Hands-on] [More comprehensive hands-on with Redux and React](http://teropa.info/blog/2015/09/10/full-stack-redux-tutorial.html)\n\n9. [Reading] [Redux best practices](https://medium.com/lexical-labs-engineering/redux-best-practices-64d59775802e#.v34syy9ia)\n\n10. [Reading + Hands-on] [Redux Saga](http://yelouafi.github.io/redux-saga/)\n\n11. Everything - [Awesome Redux](https://github.com/xgrommx/awesome-redux)\n\n## Development Workflow\n\nHere is a suggested development workflow that works for me:\n\n1. Define the routes, which helps to reason about the needed containers and components.\n\n2. Implement dump components + props (state and actions).\n\t* Each component should define `.propTypes` for prop's validation, which will throw a warning if the container that uses it do not provides all the props that the component need.\n\t\n3. Often, a container = a route page; a container is also where you import necessary components, actions and states (pass down to component) to form a single page.\n\t* if a container wants to \"pre-populate\" data during server rendering process, assign `Container.preload` with sagas that fetches necessary data from the API server. (refer to `containers/App.js` for an example)\n\n4. Implement necessary Actions as you define needed containers and components (PS: this implementation is independent from previous steps). It often helps maintainability and readability if action methods are categorized into 2:\n    * Actions that manipulate store directly through reducers (e.g. `actions/index.js \u003e createRequestTypes` method), often to update the state and trigger re-render the components. \n    * \"LOAD\" or \"TRIGGER\" actions for starting a saga routine/daemon, often to make network call.\n\n5. Implement Reducers. As you implemented the actions, you will have better idea on how to modify the states for different actions. \n\n### Using Redux DevTools\n\n[Redux Devtools](https://github.com/gaearon/redux-devtools) are enabled by default in development.\n\n- \u003ckbd\u003eCTRL\u003c/kbd\u003e+\u003ckbd\u003eH\u003c/kbd\u003e Toggle DevTools Dock\n- \u003ckbd\u003eCTRL\u003c/kbd\u003e+\u003ckbd\u003eQ\u003c/kbd\u003e Move DevTools Dock Position\n- see [redux-devtools-dock-monitor](https://github.com/gaearon/redux-devtools-dock-monitor) for more detailed information.\n\nIf you have the\n[Redux DevTools chrome extension](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd) installed it will automatically be used on the client-side instead.\n\nIf you want to disable the dev tools during development, set `__DEVTOOLS__` to `false` in `/webpack/dev.config.js`.\nDevTools are not enabled during production.\n\n## Deployment\n\n`$ npm run build`\n\n`$ npm run start`\n\n## How Everything Works?\n\nWhat initially gets run is `bin/server.js`, which does little more than enable ES6 and ES7 awesomeness in the\nserver-side node code. It then initiates `server.js`. In `server.js` we perform data fetching using Redux Saga ([details](https://github.com/yelouafi/redux-saga/issues/13#ref-commit-3e8321c)). Aside from serving the favicon and static content from `/static`, the only thing `server.js` does is initiate delegate rendering to `react-router`. At the bottom of `server.js`, we listen to port `3000` and initiate the API server.\n\n### Routing and HTML return\n\nThe primary section of `server.js` generates an HTML page with the contents returned by `react-router`. Then we perform [server-side data fetching](#server-side-data-fetching), wait for the data to be loaded, and render the page with the now-fully-loaded `redux` state.\n\nThe last interesting bit of the main routing section of `server.js` is that we swap in the hashed script and css from the `webpack-assets.json` that the Webpack Dev Server – or the Webpack build process on production – has spit out on its last run. You won't have to deal with `webpack-assets.json` manually because [webpack-isomorphic-tools](https://github.com/halt-hammerzeit/webpack-isomorphic-tools) take care of that.\n\nWe also spit out the `redux` state into a global `window.__data` variable in the webpage to be loaded by the client-side `redux` code.\n\n### Server-side Data Fetching\n\nThe [redux-saga](https://github.com/yelouafi/redux-saga) provides a mechanism for server-side data fetching from the actual backend API servers/services, when it reaches client-side (React) there is no need to do additional network call. You have to define the Sagas that a container need (refers to `containers/UserPage.js \u003e UserPage.preload` for example) for server-side to fetch. PS: You have the flexibility to implement additional logic (e.g. handle authentication) when fetching data at server-side rendering stage, as it differs from client-side. \n\n### Client Side\n\nThe client side entry point is reasonably named `client.js`. All it does is load the routes, initiate `react-router`, rehydrate the redux state from the `window.__data` passed in from the server, and render the page over top of the server-rendered DOM. This makes React enable all its event listeners without having to re-render the DOM.\n\n### Redux Middleware\n\nCurrently, we only use Saga Middleware and Logger Middleware (for development). If you need to use or add custom middlewares, you can do so by modifying `store/configureStore.dev.js` (for dev env) or `store/configureStore.prod.js` (for prod env).\n\n### Handling Authentication\n\nIf you want to implement authentication/authorization feature, follow this issue posted on redux-saga repo - [Question: Authentication flow](https://github.com/yelouafi/redux-saga/issues/14) - it is my main source of reference.\n\n### Unit Tests\n\nThe project uses [Jest](https://facebook.github.io/jest) to run your unit tests and the [Test Utilities](http://facebook.github.io/react/docs/test-utils.html) from Facebook api.\n\nAn example is available at `components \u003e User`.\n\nTo run the tests in the project, just simply run `npm test`.\n\n## Styling\n\n### Local Styles\n\nThis project uses [local styles](https://medium.com/seek-ui-engineering/the-end-of-global-css-90d2a4a06284) using [css-loader](https://github.com/webpack/css-loader). The way it works is that you import your stylesheet at the top of the `render()` function in your React Component, and then you use the classnames returned from that import. Like so:\n\n`render() { const styles = require('./App.scss'); }`\n\nThen you set the `className` of your element to match one of the CSS classes in your SCSS file, and you're good to go!\n\n`\u003cdiv className={styles.mySection}\u003e ... \u003c/div\u003e`\n\n### Global Style Variables\n\n`react-universal-saga` support global style variables by defining the variable in `theme/style.scss`. Once defined, you can use in any scss file so long it is imported (refer to `RepoPage.scss` for example). \n\n## Notable Alternatives\n\n* [Next.js](https://github.com/zeit/next.js)\n* [create-react-app](https://github.com/facebookincubator/create-react-app)\n* [react-universally](https://github.com/ctrlplusb/react-universally)\n* [react-boilerplate](https://github.com/mxstbr/react-boilerplate)\n* [react-server](https://github.com/redfin/react-server)\n* [retax](https://github.com/retaxJS/retax)\n\nAny contribution is welcome.\n\nCheers,\n\nKawi\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxkawi%2Freact-universal-saga","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxkawi%2Freact-universal-saga","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxkawi%2Freact-universal-saga/lists"}