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/validator

Debugging 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-snap

react-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

  1. fix react-hot-loader issues (4.6.5)
  2. add <Link /> in <LanguageSwitcher />
  3. add routes with data coming from API
  4. 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-cli
gatsby new my-ssr-site

GatsbyJS

yarn develop
yarn build

GatsbyJS

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&#39;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-dom

Next.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 Home

Next.js

TODO

  1. add routes with data coming from API (getInitialProps)
  2. configure dynamic routing with next-routes
  3. 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

  1. setup repo
  2. create project on Netlify

Branches builds

.TOML file

Environment Variables

Thanks.

Prerendering + Netlify

By Michał Przyszczypkowski

Prerendering + Netlify

  • 323