Simple universal React apps with Next.js
Server side rendering (SSR)?
- It's "Faster"
- Better SEO
Pros
Faster initial load
Better SEO
Cons
Slower TTFB
(Time to first byte)
Greater Complexity
Pros
Faster initial load
Better SEO
Cons
Slower TTFB
(Time to first byte)
Greater Complexity
https://medium.com/walmartlabs/the-benefits-of-server-side-rendering-over-client-side-rendering-5d07ff2cefe8
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="/manifest.json">
<link rel="shortcut icon" href="/favicon.ico">
<!--
Notice the use of in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
<script type="text/javascript" src="/static/js/bundle.js"></script></body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charSet="utf-8" class="next-head" />
<link rel="preload" href="/_next/9a92b3b0-d779-4754-83ba-bf499bdbcd93/page/index.js" as="script" />
<link rel="preload" href="/_next/9a92b3b0-d779-4754-83ba-bf499bdbcd93/page/_error.js" as="script" />
<link rel="preload" href="/_next/c3ecb62c24f9c6290c07c14368b96e2f/app.js" as="script" />
</head>
<body>
<div>
<div id="__next">
<div data-reactroot="">
<div>
<h1>Next Chefs</h1>
<div><a href="/episode?id=tt4383018">Massimo Bottura</a></div>
<div><a href="/episode?id=tt4360158">Dan Barber</a></div>
<div><a href="/episode?id=tt4360152">Francis Mallmann</a></div>
<div><a href="/episode?id=tt4338616">Niki Nakayama</a></div>
<div><a href="/episode?id=tt4338608">Ben Shewry</a></div>
<div><a href="/episode?id=tt4360160">Magnus Nilsson</a></div>
</div>
</div>
</div>
<div id="__next-error"></div>
</div>
<div>
<script>
__NEXT_DATA__ = {
"props": {
"series": {
"Title": "Chef's Table",
"Season": "1",
"totalSeasons": "3",
"Episodes": [{
"Title": "Massimo Bottura",
"Released": "2015-04-26",
"Episode": "1",
"imdbRating": "8.5",
"imdbID": "tt4383018"
}, {
"Title": "Dan Barber",
"Released": "2015-02-12",
"Episode": "2",
"imdbRating": "7.7",
"imdbID": "tt4360158"
}, {
"Title": "Francis Mallmann",
"Released": "2015-04-26",
"Episode": "3",
"imdbRating": "8.3",
"imdbID": "tt4360152"
}, {
"Title": "Niki Nakayama",
"Released": "2015-04-26",
"Episode": "4",
"imdbRating": "8.0",
"imdbID": "tt4338616"
}, {
"Title": "Ben Shewry",
"Released": "2015-04-26",
"Episode": "5",
"imdbRating": "7.7",
"imdbID": "tt4338608"
}, {
"Title": "Magnus Nilsson",
"Released": "2015-04-26",
"Episode": "6",
"imdbRating": "8.5",
"imdbID": "tt4360160"
}],
"Response": "True"
}
},
"pathname": "/",
"query": {},
"buildId": "9a92b3b0-d779-4754-83ba-bf499bdbcd93",
"buildStats": {
"app.js": {
"hash": "c3ecb62c24f9c6290c07c14368b96e2f"
}
},
"assetPrefix": "",
"nextExport": false,
"err": null,
"chunks": []
}
module = {}
__NEXT_LOADED_PAGES__ = []
__NEXT_LOADED_CHUNKS__ = []
__NEXT_REGISTER_PAGE = function(route, fn) {
__NEXT_LOADED_PAGES__.push({
route: route,
fn: fn
})
}
__NEXT_REGISTER_CHUNK = function(chunkName, fn) {
__NEXT_LOADED_CHUNKS__.push({
chunkName: chunkName,
fn: fn
})
}
</script>
<script async="" id="__NEXT_PAGE__/" type="text/javascript" src="/_next/9a92b3b0-d779-4754-83ba-bf499bdbcd93/page/index.js"></script>
<script async="" id="__NEXT_PAGE__/_error" type="text/javascript" src="/_next/9a92b3b0-d779-4754-83ba-bf499bdbcd93/page/_error.js"></script>
<div></div>
<script type="text/javascript" src="/_next/c3ecb62c24f9c6290c07c14368b96e2f/app.js" async=""></script>
</div>
</body>
</html>
Why Next.js?
- Automatic code splitting
- Page based routing
- Sensible defaults
- Easily Customizable
- Good developer experience. Short README. HMR.
*pages/ - Points of entry
lib/ - data-fetching and helpers
components/ - Standalone components
static/ - Static assets
App Structure
Router
Link allows you to "prefetch" routes
Exposes router HOC (Higher order component)
Custom server routes
getInitialProps
- Only used in pages
- Returns data to populate props
- Can be used in stateless pages
- Executes on the server for the initial page load, then on client when routing.
const Page = ({ stars }) =>
<div>
Next stars: {stars}
</div>
Page.getInitialProps = async ({ req }) => {
const res = await fetch('https://api.github.com/repos/zeit/next.js')
const json = await res.json()
return { stars: json.stargazers_count }
}
export default Page
Resources
https://medium.com/walmartlabs/the-benefits-of-server-side-rendering-over-client-side-rendering-5d07ff2cefe8
https://css-tricks.com/server-side-react-rendering/
https://github.com/zeit/next.js/
https://learnnextjs.com/
Simple Universal React Apps with Next.js
By louisnovick
Simple Universal React Apps with Next.js
- 300