A React Server Side rendered application template (isomorphic) with support fetch data like Next.js using React Router
Note: Updated project for using react@17 🔥
Note: Updated to webpack v5 🔥
🔥 Using React Router.
🔥 Support React Hot Reloading
🔥 Code splitting by loadable-components, recommended solution by React Team
🔥 Code validation with eslint and airbnb.
🔥 Code formatting with prettier.
🔥 Style validation and formatter with stylelint.
🔥 Unit testing with jest and react-testing-library.
🔥 Support postCSS.
🔥 Support SASS/SCSS by default. Import all your SASS/SCSS files in styles/App.scss.
🔥 You can extends configs and setup your needs. All webpack configs are in webpacks directory.
NodeJsv10 aboveyarn
Note: this project relay on yarn and node_modules will relay on that. it will throw error if you use npm to run commands.
1- git clone this project.
2- remove .git folder.
3- yarn install
4- yarn start
now start coding !!
you can see in http://localhost:3000.
1- Run yarn build. a build folder will be created that ready for deployment.
2- Now serve the build folder with NodeJs.
node build/server.js
note: Suggest using pm2
All route components with a static property called getInitialData can fetch data on server and pass down data as props called initialData.
you can see examples in screens/Projects.jsx or screens/About.jsx.
2- add a static async getInitialData to the a route component:
- after component definition:
Component.getInitialData = async ({ match, req, res, history, location }) {
const api = await axios.get('https://jsonplaceholder.typicode.com/users');
return { ...api.data };
}
- or during component definition:
const Component = () => {
static async getInitialData({ match, req, res, history, location }) {
const api = await axios.get('https://jsonplaceholder.typicode.com/users');
return { ...api.data };
}
}
note: we use axios because support node.js and browser.
3- now you can access your fetched data as initialData component props;
- match (matched route, both on server and client)
- req (request object ExpressJs, only server)
- res (response object ExpressJs, only server)
- history (react router history, only client)
- location (react router location, only client)
initialData: fetched data for SSR. If you don't make SSR this component it will benull.reFetch: fetch again data by callinggetInitialDataif provided in componentisLoading: loading when getting data withgetInitialData.RouteComponentPropsprovided byreact-router. You can see them here withRouter
you can use react-helmet like before in your components.
Code splitting in this project implemented by loadable-components.
For routes component you should use our asyncComponent in routes.js file. the asyncComponent will take care of code splitting and getInitialData if provided on component. see usage in routes.js.
example:
asyncComponent(()=> import("./screens/Projects.jsx"))
for other components you could see loadable-components documents. but as a short example:
import loadable from '@loadable/component'
const OtherComponent = loadable(() => import('./OtherComponent'))
function MyComponent() {
return (
<div>
<OtherComponent />
</div>
)
}
Please visit loadable-components documents for advanced usages and configuration.
Inside asyncComponent we use a simple loading ... message until component loaded completely. If you want you can customize it.
1- create folder __tests__ under your component directory.
2- create file with filename.test.js or filename.spec.js. for example Projects.spec.js.
3- write tests.
4- enter yarn test for run tests, or yarn test:watch to run in watch mode.
note: you can create test file without __tests__ folder but for better file structure keep it in __tests__.
