Prerendering + Netlify
Server Side Rendering
Why?
Server Side Rendering
- speed of FMP
- SEO (not Google)
- social sharing
Debugging social share
https://developers.facebook.com/tools/debug/sharing/https://cards-dev.twitter.com/validatorDebugging social share


react-snap
How it works?
react-snap
- crawls website starting from given url
- generates static pages
react-snap
Pros?
react-snap
- easy setup
- generates dynamic routes
react-snap
Cons?
react-snap
- only suitable for static content
react-snap
configuration
yarn add --dev react-snapreact-snap
configuration
{
"scripts": {
"postbuild": "react-snap"
}
}react-snap
configuration
import { hydrate, render } from "react-dom";
const rootElement = document.getElementById("root");
if (rootElement.hasChildNodes()) {
hydrate(<App />, rootElement);
} else {
render(<App />, rootElement);
}react-snap
TODO
- fix react-hot-loader issues (4.6.5)
- add <Link /> in <LanguageSwitcher />
- add routes with data coming from API
- configure <Helmet />
GatsbyJS
GatsbyJS
How it works?
GatsbyJS
- generates static pages
- provides API specifically for this purpose
GatsbyJS
Pros
- provides rich API for generating pages
- works nicely with GraphQL
- strong community
- allows hybrid approach
- follows modern stack out of the box (service workers, offline, caching, lazy loading, etc)
- follows PRPL (Push, Render, Pre-Cache, Lazy-load) out of the box [https://www.gatsbyjs.org/docs/prpl-pattern/]
GatsbyJS
Cons
- only suitable for static content
- requires opinionated approach & code structure
- hard to include in existing SPA project
GatsbyJS
npm install -g gatsby-cligatsby new my-ssr-siteGatsbyJS
yarn developyarn buildGatsbyJS
import React from "react"
import Layout from "../components/layout"
import SEO from "../components/seo"
const NotFoundPage = () => (
<Layout>
<SEO title="404: Not found" />
<h1>NOT FOUND</h1>
<p>You just hit a route that doesn't exist... the sadness.</p>
</Layout>
)
export default NotFoundPage
src/pages/404.js
GatsbyJS
import React from "react";
import { Link } from "gatsby";
import { Helmet } from 'react-helmet';
const IndexPage = ({ pageContext: { data }}) => (
<div style={{ textAlign: 'center' }}>
<Helmet title="Homepage - Pokemon App" />
<div>
{data.map((item) =>
<div key={item.name}>
<Link to={'/details/' + item.name}>{item.name}</Link>
</div>
)}
</div>
</div>
);
export default IndexPage;
src/templates/index.js
GatsbyJS
const fetch = require('isomorphic-fetch');
const getAllPokemon = async () => {
const rawData = await fetch('https://pokeapi.co/api/v2/pokemon?limit=10');
const { results } = await rawData.json();
return results;
};gatsby-node.js
GatsbyJS
exports.createPages = async ({ actions: { createPage } }) => {
createPage({
// page route
path: `/`,
// template file
component: require.resolve("./src/templates/page-template.js"),
// context data passed to the template
context: {},
});
};gatsby-node.js
GatsbyJS
exports.createPages = async ({ actions: { createPage } }) => {
const allPokemon = await getAllPokemon();
createPage({
path: `/`,
component: require.resolve("./src/templates/all.js"),
context: { data: allPokemon },
});
};gatsby-node.js
GatsbyJS
exports.createPages = async ({ actions: { createPage } }) => {
const allPokemon = await getAllPokemon();
createPage({
path: `/`,
component: require.resolve("./src/templates/all.js"),
context: { data: allPokemon },
});
allPokemon.forEach(async ({ name }) => {
createPage({
path: `/details/${name}/`,
component: require.resolve("./src/templates/details.js"),
context: { name },
});
});
};gatsby-node.js
Next.js
How it works?
Next.js
- uses node.js serwer to render universal React app
- is able to export routes as static files
Next.js
Pros?
Next.js
- easy production ready setup
- provides lots of plugins
- is suitable for dynamic content
- is highly configurable and gives possibilities such as caching
Next.js
Cons?
Next.js
- it enforces certain project structure
- universal code is harder to maintain
- cannot be easily adapted to react-scripts-apptension
Next.js
configuration
yarn add next react react-domNext.js
configuration
{
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
}
}Next.js
configuration
function Home() {
return <div>Welcome to Next.js!</div>
}
export default HomeNext.js
TODO
- add routes with data coming from API (getInitialProps)
- configure dynamic routing with next-routes
- configure meta tags with next/head
Netlify
Netlify
How it works?
Netlify
Caches rendered pages and serves them for SEO / social bots
Netlify
Pros?
Netlify
- Zero configuration - easy to setup
- No need for any implementation adjustments
- Works for all SEO bots, Facebook, Twitter, etc
- Works with dynamic content
Netlify
Cons?
Netlify
- Can't control server response
- Non-configurable
- It's not a universal app
- Don't affect FMP (only works for bots)
Netlify
configuration
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
netlify.toml
Netlify
configuration

Netlify
configuration

Build & Deploy / Post processing
Netlify
- setup repo
- create project on Netlify
Branches builds
.TOML file
Environment Variables
Thanks.
Prerendering + Netlify
By Michał Przyszczypkowski
Prerendering + Netlify
- 323