{"id":14385020,"url":"https://github.com/dimaip/server-side-rendering","last_synced_at":"2025-09-01T20:35:29.836Z","repository":{"id":73287866,"uuid":"58616981","full_name":"dimaip/server-side-rendering","owner":"dimaip","description":"Interactive guide to server-side rendering with Webpack, React, React Transmit, CSS modules and more","archived":false,"fork":false,"pushed_at":"2016-12-21T15:37:00.000Z","size":10,"stargazers_count":351,"open_issues_count":2,"forks_count":21,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-24T08:43:12.897Z","etag":null,"topics":["babel","react-transmit","reactjs","server-side-rendering","webpack"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dimaip.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2016-05-12T07:08:46.000Z","updated_at":"2025-03-15T07:50:31.000Z","dependencies_parsed_at":null,"dependency_job_id":"d151aee0-12b1-4367-a7ae-929369b6b640","html_url":"https://github.com/dimaip/server-side-rendering","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimaip%2Fserver-side-rendering","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimaip%2Fserver-side-rendering/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimaip%2Fserver-side-rendering/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimaip%2Fserver-side-rendering/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dimaip","download_url":"https://codeload.github.com/dimaip/server-side-rendering/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246927839,"owners_count":20856198,"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":["babel","react-transmit","reactjs","server-side-rendering","webpack"],"created_at":"2024-08-28T18:01:52.197Z","updated_at":"2025-04-03T03:13:47.348Z","avatar_url":"https://github.com/dimaip.png","language":"JavaScript","readme":"# Interactive Guide to Server-side rendering with Webpack, React, React Transmit, CSS modules and more\n\nFollow the tutorial commit-by-commit, to see the server-side rendering drama unfold with a happy ending!\n\n[CLICK TO GET STARTED](https://github.com/dimaip/server-side-rendering/commits/master)\n\n\n## Contents (mostly for Google)\n\n### [Step 1: minimal Webpack, Babel and React setup](https://github.com/dimaip/server-side-rendering/commit/7d1d0677bca0ea94e820dc7e156c89e83ef823bb)\n\nRUN: `npm run start` and then open index.html in the browser.\n\nWebpack helps us to bundle our code with dependencies from npm\n(such as React), and then transforms the code with Babel, to make\nit compatible with ES5.\n\n### [Step 2: trivial server-side rendering with Express](https://github.com/dimaip/server-side-rendering/commit/fad6b64e4ec3ee6b378c6ab0abd36f03fdba7c77)\n\nRUN: `npm run start` and go to `http://localhost:3000`.\n\nNow we are rendering the same Hello component both on client and server:\nwith express server we pre-render the Hello component on the server, and\nserver the client with rendered html, and with webpack we continue to\nbundle client.js into ES5 code that the browser would understand,\njust as we did at previous step.\n\n### [Step 3: add styles](https://github.com/dimaip/server-side-rendering/commit/53d2ffa7bc9319722addced5bb94c5b231726a1b)\n\nNow lets learn to deal with styles. We configure webpack loaders to\nsupport loading CSS files. This is cool, but there comes one problem\nwith server-side rendering: styles won't be loaded until all of JS loads,\nso no styles for devices without JS.\n\nLet's fix this problem with webpack's ExtractTextPlugin plugin: it\nextracts all CSS styles into one CSS file that we can serve to our client,\nso our page will instantly look perfectly styled, even without JS.\n\n### [Step 3a: switch to CSS modules](https://github.com/dimaip/server-side-rendering/commit/e2c02444b1e7c6ec349511aa9b2da1a52aba5474)\n\nEverybody loves CSS modules, and the great news is that they come free with Webpack.\nThe bad news is that we can't use them with server-side rendering, as we don't use\nWebpack when rendering on the server-side.\n\nSo at this step we broke everything, and the only way to continue from here, is to\nstart using Webpack to pre-build code for server-side rendering too, and that's\nwhat we'll do at the next step.\n\n### [Step 3b: save the day by making webpack to render server-side code](https://github.com/dimaip/server-side-rendering/commit/6e36b9690816d414ca36775c6487e0b6dbd8abe3)\n\nTo save our issue with CSS modules, we make Webpack to render both\nour client and our server side code. The best way to do it is to\nuse Webpack's abillity to handle array of configs.\n\nWith first config we transform our client-side code (`client.js`),\njust as we were doing before. But with the second config we transform\n`handleRender` function that we have extracted into `serverEntry.js`,\nso now our server-side rendering code gets processed by Webpack too.\nThere we use css-loader/locals as a CSS loader, to just get class names from\nCSS modules, as that's all we need to render html on the server.\nAlso notice how we use `target:node` and `nodeExternals`.\n\nGreat! Now our build is fixed, so we can use CSS modules both during client\nand server rendering.\n\n\n### [Step 4a: asyncronously fetching data](https://github.com/dimaip/server-side-rendering/commit/d9ce281b88d142cf52861223a201de6d47dfd428)\n\nNow let's fetch some data asyncronously. We'll use isomorphic-fetch,\nas it works both on client and server our of the box.\n\nFetching data works just fine on the server, but the problem is that\non the server we didn't wait for fetch to finish fetching the data\nbefore sending the response, so our pre-rendered html doesn't have any\nasync data when it arrives.\nLet's try to fix it in the next step.\n\n\n### [Step 4b: use react-transmit to declaratively define data deps](https://github.com/dimaip/server-side-rendering/commit/HEAD)\n\nThere are multiple ways to solve async rendering issue. Here we'll\nuse react-transmit to declaratively define our data dependencies per component,\nand return rendered html only when all data is resolved.\n\nIt works even with nested components, constructing the single promises tree,\nwhich is qute cool. It is inspired by Facebook Relay, so if you are familiar\nwith it, you'll feel right at home.\n\n\n## That's all, folks!\n\nGot more tips or challenges with server-side rendering of React? Submit a PR!\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdimaip%2Fserver-side-rendering","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdimaip%2Fserver-side-rendering","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdimaip%2Fserver-side-rendering/lists"}