{"id":13494113,"url":"https://github.com/bertho-zero/react-redux-universal-hot-example","last_synced_at":"2025-05-16T09:05:50.257Z","repository":{"id":57248578,"uuid":"60562752","full_name":"bertho-zero/react-redux-universal-hot-example","owner":"bertho-zero","description":"A starter boilerplate for a universal webapp using react, redux, express and feathers","archived":false,"fork":false,"pushed_at":"2020-06-02T13:48:05.000Z","size":17609,"stargazers_count":632,"open_issues_count":74,"forks_count":165,"subscribers_count":40,"default_branch":"master","last_synced_at":"2025-05-13T05:44:59.400Z","etag":null,"topics":["boilerplate","feathersjs","offline-first","progressive-web-app","react","redux","starter-kit","universal"],"latest_commit_sha":null,"homepage":"https://react-hot-example.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/bertho-zero.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-06-06T21:41:13.000Z","updated_at":"2025-05-08T21:37:56.000Z","dependencies_parsed_at":"2022-08-24T16:11:11.712Z","dependency_job_id":null,"html_url":"https://github.com/bertho-zero/react-redux-universal-hot-example","commit_stats":null,"previous_names":[],"tags_count":1,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bertho-zero%2Freact-redux-universal-hot-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bertho-zero%2Freact-redux-universal-hot-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bertho-zero%2Freact-redux-universal-hot-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bertho-zero%2Freact-redux-universal-hot-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bertho-zero","download_url":"https://codeload.github.com/bertho-zero/react-redux-universal-hot-example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254501557,"owners_count":22081528,"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":["boilerplate","feathersjs","offline-first","progressive-web-app","react","redux","starter-kit","universal"],"created_at":"2024-07-31T19:01:21.995Z","updated_at":"2025-05-16T09:05:45.213Z","avatar_url":"https://github.com/bertho-zero.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Resources"],"sub_categories":["Examples"],"readme":"\n# React Redux Universal Hot Example\n\n[![Build Status](https://travis-ci.org/bertho-zero/react-redux-universal-hot-example.svg?branch=master\u0026style=flat-square)](https://travis-ci.org/bertho-zero/react-redux-universal-hot-example)\n[![Dependency Status](https://david-dm.org/bertho-zero/react-redux-universal-hot-example.svg?style=flat-square)](https://david-dm.org/bertho-zero/react-redux-universal-hot-example)\n[![devDependency Status](https://david-dm.org/bertho-zero/react-redux-universal-hot-example/dev-status.svg?style=flat-square)](https://david-dm.org/bertho-zero/react-redux-universal-hot-example?type=dev)\n\n---\n\n## About\n\nThis is a starter boilerplate app I've put together using the following technologies:\n\n* ~~Isomorphic~~ [Universal](https://medium.com/@mjackson/universal-javascript-4761051b7ae9) rendering\n* Both client and server make calls to load data from separate API server\n* [React](https://github.com/facebook/react)\n* [React Router](https://github.com/reactjs/react-router)\n* [Express](http://expressjs.com)\n* [Feathers](http://feathersjs.com/)\n* [Passport](http://passportjs.org), [feathers-authentication](https://github.com/feathersjs/feathers-authentication) and [redux-auth-wrapper](https://github.com/mjrussell/redux-auth-wrapper) for authentication\n* [Babel](http://babeljs.io) for ES6 and ES7 magic\n* [Webpack](https://webpack.js.org/) 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](https://github.com/reactjs/redux)'s futuristic [Flux](https://facebook.github.io/react/blog/2014/05/06/flux.html) implementation\n* [Redux Dev Tools](https://github.com/reactjs/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* [react-final-form](https://github.com/final-form/react-final-form) to manage form state\n* [lru-memoize](https://github.com/erikras/lru-memoize) to speed up form validation\n* [multireducer](https://github.com/erikras/multireducer) to combine single reducers into one key-based reducer\n* [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) to customize Bootstrap\n* [font-awesome](https://github.com/FortAwesome/Font-Awesome)\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\nI cobbled this together from a wide variety of similar \"starter\" repositories. As I post this in June 2015, all of these libraries are right at the bleeding edge of web development. They may fall out of fashion as quickly as they have come into it, but I personally believe that this stack is the future of web development and will survive for several years. I'm building my new projects like this, and I recommend that you do, too.\n\n## Features\n\n\u003cdl\u003e\n  \u003cdt\u003eHot reload\u003c/dt\u003e\n  \u003cdd\u003eEnjoy the developer experience! Your saved changes to the CSS and JS are reflected instantaneously without refreshing the page ! On the server as on the client.\n  Preserving the state of application on the client.\u003c/dd\u003e\n\n  \u003cdt\u003eNext generation JavaScript\u003c/dt\u003e\n  \u003cdd\u003eUse JSX syntax with all ES6 features, and some of ES7 (see \u003ca href=\".babelrc\"\u003e.babelrc\u003c/a\u003e).\u003c/dd\u003e\n\n  \u003cdt\u003eCSS in modules\u003c/dt\u003e\n  \u003cdd\u003eWrite composable, modular and maintenable CSS with your components.\u003c/dd\u003e\n\n  \u003cdt\u003ePredictable state management\u003c/dt\u003e\n  \u003cdd\u003eUnidirectional data flow with \u003ca href=\"http://redux.js.org\"\u003eRedux\u003c/a\u003e helps you write applications that behave consistently and are easy to test. On top of that, it provides a great developer experience.\u003c/dd\u003e\n\n  \u003cdt\u003eBackend API oriented services\u003c/dt\u003e\n  \u003cdd\u003eWith \u003ca href=\"http://feathersjs.com\"\u003eFeathers\u003c/a\u003e it's easy to create scalable real-time applications with services and hooks. \n  \u003ca href=\"https://en.wikipedia.org/wiki/Cross-cutting_concern\"\u003eCross cutting concerns\u003c/a\u003e are an extremely powerful part of aspect oriented programming. They are a very good fit for web and mobile applications since the majority are primarily CRUD applications with lots of shared functionality. You can create before and after hooks and chain them together to create very complex processes while still maintaining modularity and flexibility.\u003c/dd\u003e\n\n  \u003cdt\u003eAuthentication\u003c/dt\u003e\n  \u003cdd\u003e\u003ca href=\"http://passportjs.org\"\u003ePassport\u003c/a\u003e authentication allows you to use all the desired strategies. The connections in REST and in real time are protected in the same way with the hooks. React-router, redux and \u003ca href=\"https://github.com/mjrussell/redux-auth-wrapper\"\u003eredux-auth-wrapper\u003c/a\u003e allow you to keep control in your React app.\u003c/dd\u003e\n\n  \u003cdt\u003eProgressive wep app \u0026 Offline-first\u003c/dt\u003e\n  \u003cdd\u003eProgressive Web Apps are user experiences that have the reach of the web, and are:\u003cbr\u003e\nReliable - Load instantly and never show the downasaur, even in uncertain network conditions.\u003cbr\u003e\nFast - Respond quickly to user interactions with silky smooth animations and no janky scrolling.\u003cbr\u003e\nEngaging - Feel like a natural app on the device, with an immersive user experience.\u003cbr\u003e\u003cbr\u003e\nThis new level of quality allows Progressive Web Apps to earn a place on the user's home screen.\u003c/dd\u003e\n\n  \u003cdt\u003eLazy loading \u0026 dynamic routing\u003c/dt\u003e\n  \u003cdd\u003eThe code splitting makes the size of your main bundle almost fixed, and with react-router you can load application pieces on demand. You can send bundles to people who are only trained, such as administration.\u003c/dd\u003e\n\n  \u003cdt\u003eUniversal rendering\u003c/dt\u003e\n  \u003cdd\u003eWith the help of server side rendering the first rendering is never empty and performance is better. This is the time for example to prefetch the data.\n\u003ca href=\"https://github.com/halt-hammerzeit/webpack-isomorphic-tools\"\u003eWebpack-isomorphic-tools\u003c/a\u003e to allow require() work for statics both on client and server.\u003c/dd\u003e\n\n  \u003cdt\u003eSEO\u003c/dt\u003e\n  \u003cdd\u003eThis project supports SEO for search engines even without support indexing of JavaScript content, thanks to server-side rendering.\u003c/dd\u003e\n\u003c/dl\u003e\n\n## Installation\n\n```bash\nyarn\n```\n\n## Running Dev Server\n\n```bash\nyarn dev\n```\n\nThe first time it may take a little while to generate the first `webpack-assets.json` and complain with a few dozen `[webpack-isomorphic-tools] (waiting for the first Webpack build to finish)` printouts, but be patient. Give it 30 seconds.\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 [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 by default.\n\n## Building and Running Production Server\n\n```bash\nyarn build\nyarn start\n```\n\n## Demo\n\nA demonstration of this app can be seen [running on heroku](https://react-hot-example.herokuapp.com/), which is a deployment of the [heroku branch](https://github.com/bertho-zero/react-redux-universal-hot-example/tree/heroku).\n\n## Explanation\n\nWhat initially gets run is `bin/server.js`, which does little more than enable ES6 and ES7 awesomeness in the server-side node code. It then initiates `server.js`. In `server.js` we proxy any requests to `/api/*` to the API server, running at `localhost:3030`. All the data fetching calls from the client go to `/api/*`. 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`. First we instantiate an `ApiClient`, a facade that both server and client code use to talk to the API server. On the server side, `ApiClient` is given the request object so that it can pass along the session cookie to the API server to maintain session state. We pass this API client facade to the `redux` middleware so that the action creators have access to it.\nYou can also use `app` for RESTful calls to api.\n\nThen 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 [redial](https://www.npmjs.com/package/redial) package exposes an API to return promises that need to be fulfilled before a route is rendered. It exposes a `\u003cReduxAsyncConnect /\u003e` container, which wraps our render tree on both [server](https://github.com/bertho-zero/react-redux-universal-hot-example/blob/master/src/server.js) and [client](https://github.com/bertho-zero/react-redux-universal-hot-example/blob/master/src/client.js). More documentation is available on the [redial](https://www.npmjs.com/package/redial) page.\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\nThe middleware, [`clientMiddleware.js`](https://github.com/bertho-zero/react-redux-universal-hot-example/blob/master/src/redux/middleware/clientMiddleware.js), serves two functions:\n\n1. To allow the action creators access to the client API facade. Remember this is the same on both the client and the server, and cannot simply be `import`ed because it holds the cookie needed to maintain session on server-to-server requests.\n2. To allow some actions to pass a \"promise generator\", a function that takes the API client and returns a promise. Such actions require three action types, the `REQUEST` action that initiates the data loading, and a `SUCCESS` and `FAILURE` action that will be fired depending on the result of the promise. There are other ways to accomplish this, some discussed [here](https://github.com/reactjs/redux/issues/99), which you may prefer, but to the author of this example, the middleware way feels cleanest.\n\n#### Redux Modules... *What the Duck*?\n\nThe `src/redux/modules` folder contains \"modules\" to help\nisolate concerns within a Redux application (aka [Ducks](https://github.com/erikras/ducks-modular-redux), a Redux Style Proposal that I came up with). I encourage you to read the\n[Ducks Docs](https://github.com/erikras/ducks-modular-redux) and provide feedback.\n\n#### Getting data and actions into components\n\nTo understand how the data and action bindings get into the components – there's only one, `InfoBar`, in this example – I'm going to refer to you to the [Redux](https://github.com/gaearon/redux) library. The only innovation I've made is to package the component and its wrapper in the same js file. This is to encapsulate the fact that the component is bound to the `redux` actions and state. The component using `InfoBar` needn't know or care if `InfoBar` uses the `redux` data or not.\n\n#### Images\n\nNow it's possible to render the image both on client and server. Please refer to issue [#39](https://github.com/erikras/react-redux-universal-hot-example/issues/39) for more detail discussion, the usage would be like below (super easy):\n\n```javascript\nlet logoImage = require('./logo.png');\n```\n\n#### 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```javascript\nrender() {\nconst styles = require('./App.scss');\n...\n```\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```jsx\n\u003cdiv className={styles.mySection}\u003e ... \u003c/div\u003e\n```\n\n#### Alternative to Local Styles\n\nIf you'd like to use plain inline styles this is possible with a few modifications to your webpack configuration.\n\n**1. Configure Isomorphic Tools to Accept CSS**\n\nIn `webpack-isomorphic-tools.js` add **css** to the list of style module extensions\n\n```javascript\n    style_modules: {\n      extensions: ['less','scss','css'],\n```\n\n**2. Add a CSS loader to webpack dev config**\n\nIn `dev.config.js` modify **module loaders** to include a test and loader for css\n\n```javascript\n  module: {\n    loaders: [\n      { test: /\\.css$/, loader: 'style-loader!css-loader'},\n```\n\n**3. Add a CSS loader to the webpack prod config**\n\nYou must use the **ExtractTextPlugin** in this loader. In `prod.config.js` modify **module loaders** to include a test and loader for css\n\n```javascript\n  module: {\n    loaders: [\n      { test: /\\.css$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader')},\n```\n\n**Now you may simply omit assigning the `required` stylesheet to a variable and keep it at the top of your `render()` function.**\n\n```javascript\nrender() {\nrequire('./App.css');\nrequire('aModule/dist/style.css');\n...\n```\n\n**NOTE** In order to use this method with **scss or less** files one more modification must be made. In both `dev.config.js` and `prod.config.js` in the loaders for less and scss files remove \n\n1. `modules`\n2. `localIdentName...`\n\nBefore:\n```javascript\n{ test: /\\.less$/, loader: 'style!css?modules\u0026importLoaders=2\u0026sourceMap\u0026localIdentName=[local]___[hash:base64:5]!autoprefixer?browsers=last 2 version!less?outputStyle=expanded\u0026sourceMap' },\n```\nAfter:\n```javascript\n{ test: /\\.less$/, loader: 'style!css?importLoaders=2\u0026sourceMap!autoprefixer?browsers=last 2 version!less?outputStyle=expanded\u0026sourceMap' },\n```\n\nAfter this modification to both loaders you will be able to use scss and less files in the same way as css files.\n\n#### Unit Tests\n\nThe project uses [Jest](https://facebook.github.io/jest/) to run your unit tests.\n\nTo run the tests in the project, just simply run `yarn test` if you have `Chrome` installed, it will be automatically launched as a test service for you.\n\n## Deployment on Heroku\n\nTo get this project to work on Heroku, you need to:\n\n1. Remove the `\"PORT\": 8080` line from the `start-prod` script of `package.json`.\n2. `heroku config:set NODE_ENV=production`\n3. `heroku config:set NODE_PATH=./src`\n4. `heroku config:set NPM_CONFIG_PRODUCTION=false`\n  * This is to enable webpack to run the build on deploy.\n\nThe first deploy might take a while, but after that your `node_modules` dir should be cached.\n\n## FAQ\n\nThis project moves fast and has an active community, so if you have a question that is not answered below please file an issue.\n\n\n## Roadmap \n\nAlthough this isn't a library, we recently started versioning to make it easier to track breaking changes and emerging best practices. \n\n* [Inline Styles](docs/InlineStyles.md) - CSS is dead\n\n## Contributing\n\nI am more than happy to accept external contributions to the project in the form of feedback, bug reports and even better - pull requests :) \n\nIf you would like to submit a pull request, please make an effort to follow the guide in [CONTRIBUTING.md](CONTRIBUTING.md). \n \n---\nThanks for checking this out.\n\nCreated by:\n– Erik Rasmussen, [@erikras](https://twitter.com/erikras)\n\nMaintened by:\n– Kévin Berthommier, [@bertho-zero](https://github.com/bertho-zero)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbertho-zero%2Freact-redux-universal-hot-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbertho-zero%2Freact-redux-universal-hot-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbertho-zero%2Freact-redux-universal-hot-example/lists"}