{"id":20373353,"url":"https://github.com/frontarm/create-universal-react-app","last_synced_at":"2025-04-07T07:03:02.643Z","repository":{"id":35044906,"uuid":"200157762","full_name":"frontarm/create-universal-react-app","owner":"frontarm","description":"Configuration-free SSR for Create React App.","archived":false,"fork":false,"pushed_at":"2022-02-26T01:41:12.000Z","size":9503,"stargazers_count":126,"open_issues_count":15,"forks_count":1,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-31T06:01:33.335Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/frontarm.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG-0.x.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null}},"created_at":"2019-08-02T03:23:28.000Z","updated_at":"2024-08-17T06:23:23.000Z","dependencies_parsed_at":"2022-08-08T04:01:29.435Z","dependency_job_id":null,"html_url":"https://github.com/frontarm/create-universal-react-app","commit_stats":null,"previous_names":[],"tags_count":196,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontarm%2Fcreate-universal-react-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontarm%2Fcreate-universal-react-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontarm%2Fcreate-universal-react-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontarm%2Fcreate-universal-react-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/frontarm","download_url":"https://codeload.github.com/frontarm/create-universal-react-app/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247608150,"owners_count":20965952,"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":[],"created_at":"2024-11-15T01:17:54.477Z","updated_at":"2025-04-07T07:03:02.603Z","avatar_url":"https://github.com/frontarm.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  🌐\n  \u003cbr\u003e\n  Create Universal React App\n\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  Configuration-free SSR for Create React App\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/create-universal-react-app\"\u003e\u003cimg alt=\"NPM\" src=\"https://img.shields.io/npm/v/create-universal-react-app.svg\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n**This is a fork of Create React App. For details on Create React App itself, see the [official repository](https://github.com/facebook/create-react-app/).**\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n## Getting Started\n\n### For new projects\n\nTo create a new project with SSR, just use `npm init`:\n\n```bash\nnpm init universal-react-app my-ssr-app\n```\n\nAlternatively, you can use plain old create-react-app with a `--react-scripts universal-react-scripts` option:\n\n```bash\ncreate-react-app my-ssr-app --scripts-version universal-react-scripts\n```\n\nEither way, you'll get the standard Create React App template with one extra file: `src/index.node.js` (which is where you'll handle server side rendering).\n\n### For existing projects\n\nIn your package.json, just change the `react-scripts` dependency to `universal-react-scripts`. _You can leave the occurences of `react-scripts` in the `scripts` object as is._ Then, re-run `yarn install` or `npm install`, and add a `src/index.node.js` file:\n\n```js\nimport fs from 'fs';\nimport React from 'react';\nimport { renderToString } from 'react-dom/server';\nimport './index.css';\nimport App from './App';\n\nconst renderer = async (request, response) =\u003e {\n  // The index.html file is a template, which will have environment variables\n  // and bundled scripts and stylesheets injected during the build step, and\n  // placed at the location specified by `process.env.HTML_TEMPLATE_PATH`.\n  //\n  // To customize the rendered HTML, you can add other placeholder strings,\n  // and replace them within this function -- just as %RENDERED_CONTENT% is\n  // replaced. Note however that if you name the placeholder after an\n  // environment variable available at build time, then it will be\n  // automatically replaced by the build script.\n  let template = fs.readFileSync(process.env.HTML_TEMPLATE_PATH, 'utf8');\n  let [header, footer] = template.split('%RENDERED_CONTENT%');\n  let body = renderToString(\u003cApp /\u003e);\n  let html = header + body + footer;\n  response.send(html);\n};\n\nexport default renderer;\n```\n\nYour app will now call the function exported by `src/index.node.js` to render its HTML.\n\n_Note: if you encounter any build errors after making this change, try deleting your `node_modules` and reinstalling them from scratch._\n\n## Build output\n\nUniversal React Scripts outputs two versions of your app: a browser version, and a node version. The node version is just a common-js version of `index.node.js`, which you can import in your express app or serverless function to handle server side rendering.\n\n## `serve` script\n\nUniversal React Scripts includes a `serve` script for testing your build output:\n\n```bash\nnpm run serve\n\n# or\n\nyarn serve\n```\n\nThis launches a server for the content in the `build` folder, and when a `index.node.js` file exists, it loads the Node bundle and server the app with server rendering.\n\n## Server Rendering with Serverless / Cloud Functions\n\nCURA can be used to do serverless SSR -- for example, using Firebase Functions. To get this working, you'll need to package up the files in `build/node` and then call them within your serverless function.\n\n### With Firebase Functions\n\n**[See the example repository with routes, react-helmet and styled-components \u0026raquo;](https://github.com/jamesknelson/cura-firebase-example)**\n\nYou can create a package with your app's commonjs code by setting the `name`, `files` and `main` fields in your app's `package.json`. Once the package is configured correctly, you'll be able to use `npm pack` to create a `tgz` file that can be added as a dependency to your functions `package.json` -- which can be automated by adding a bash script as a `predeploy` step.\n\n**Changes to `package.json`:**\n\n```json\n{\n  \"name\": \"app\",\n  \"main\": \"build/node/index.js\",\n  \"files\": [\"build/node/*.*\"],\n  \"scripts\": {\n    \"deploy\": \"firebase deploy\",\n    \"predeploy\": \"sh ./scripts/pack.sh\"\n  }\n}\n```\n\n**`scripts/pack.sh`:**\n\n```bash\nrm functions/renderer.tgz\nnpm run build\nmv \"$(npm pack)\" functions/renderer.tgz\n```\n\n**`functions/package.json`:**\n\n```json\n{\n  \"optionalDependencies\": {\n    \"app\": \"./renderer.tgz\"\n  }\n}\n```\n\nThe result of these three files is that each time you call `yarn deploy` or `npm run deploy`, a version of your app's `index.node.js` file will be built, packaged, and then made available to your firebase functions. You can then import it and use it as so:\n\n```js\nconst admin = require('firebase-admin');\nconst functions = require('firebase-functions');\n\nadmin.initializeApp();\n\nlet renderer;\nif (process.env.NODE_ENV === 'production') {\n  // Load the renderer from the packaged version when deploying\n  renderer = require('app').default;\n} else {\n  // Load the renderer directly from the build directory during development.\n  // Note: the renderer is not used in development as CURA includes its own\n  // renderer, but the functions emulator fails without this.\n  renderer = require('../build/node').default;\n}\n\nexports.renderer = functions.https.onRequest(renderer);\n```\n\nFinally, if you're using Firebase Hosting, you'll need to configure it to route all non-static requests to the `renderer` function. Here's what the resulting `firebase.json` looks like:\n\n```json\n{\n  \"hosting\": {\n    \"public\": \"build/web\",\n    \"ignore\": [\"firebase.json\", \"**/.*\", \"**/node_modules/**\"],\n    \"rewrites\": [\n      {\n        \"source\": \"**\",\n        \"function\": \"renderer\"\n      }\n    ]\n  }\n}\n```\n\n_You can see an example of this setup, along with async routing, styled components and react-helmet, at the [cura-firebase-example](https://github.com/jamesknelson/cura-firebase-example) repository._\n\n## The rest is just Create React App\n\nLearn more at the [Create React App](https://facebook.github.io/create-react-app/) website.\n\nIf you'd like to understand the changes this fork makes to standard Create React App, see the [Pull Request](https://github.com/facebook/create-react-app/pull/6747).\n\n## License\n\nCreate React App is open source software [licensed as MIT](https://github.com/facebook/create-react-app/blob/master/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrontarm%2Fcreate-universal-react-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffrontarm%2Fcreate-universal-react-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrontarm%2Fcreate-universal-react-app/lists"}