refactr.tech

with gatsby

Welcome!

A special thanks to...

About me

Question for you!

overview

  • Static sites
  • GatsbyJS
  • Getting started
  • Using Graphql
  • Creating pages from data
  • Ways we made refactr.tech better

Subtitle

What is a static site?

static site benefits

  • Easier deployment
  • Cheaper to host
  • Static files respond to browser faster

gatsbyjs

  • beyond your typical static site generator

 

  • easily meet Progressive Web App standards

 

  • uses ReactJS
  • uses GraphQL to pull in data from various sources

 

  • large ecosystem of plugins

 

  • fast

React

A JavaScript library for building user interfaces.

 

It’s the framework that Gatsby uses to build pages and structure content.

 

Graphql

A query language that allows you to pull data into your website.

 

It’s the interface that Gatsby uses for managing site data.

 

Progressive web app

  • Responsive
  • Connectivity independent
  • App-like-interactions
  • Always up-to-date
  • Safe
  • Discoverable
  • Re-engageable
  • Installable
  • Linkable

refactr.tech problems

  • Hard for one person to manage

 

  • Poor user experience if you have a bad internet connection

 

  • Doesn't meet any standards of a progressive web app

getting started

Where do the files from the original refactr.tech site go?

Pages defined by react components

From HTML to JSX

Getting the data

module.exports = {
  siteMetadata: {
    title: "REFACTR.TECH"
  },
  plugins: [
    {
      resolve: `gatsby-source-airtable`,
      options: {
        apiKey: process.env.GATSBY_AIRTABLE_API_KEY,
        tables: [
          
          {
            baseId: process.env.GATSBY_AIRTABLE_BASE_KEY,
            tableName: `Speakers`,
            queryName: `speakers`,
            mapping: { headshot: `fileNode` }
          },
          {
            baseId: process.env.GATSBY_AIRTABLE_BASE_KEY,
            tableName: `Sessions`,
            queryName: `sessions`,
            tableLinks: ["Speakers"]
          }
        ]
      }
    }
  ]
}
gatsby-config.js

How did I get data onto a page?

With our GraphQL query we get back a node of data for each speaker. 

export default ({ data }) => {
  return (

    <SpeakerCardList items={data.allAirtable.edges} />

  );
};

export const speakerPageQuery = graphql`
  {
    allAirtable(filter: { table: { eq: "Speakers" } }) {
      edges {
        node {
          fields {
            slug
          }
          data {
            speaker_name
            role
            company
            twitter
            linkedIn
            company_url
          }
        }
      }
    }
  }
`;

Those nodes of data are now available on this page.

speakers.js
import React from "react";
import { SpeakerCard } from "./SpeakerCard";

export const SpeakerCardList = ({ items }) => {
  return items.map(item => (
    <SpeakerCard {...item.node.data} slug={item.node.fields.slug} />
  ));
};
import React from "react";
import Img from "gatsby-image";

export const SpeakerCard = ({
  twitter,
  linkedIn,
  headshot,
  speaker_name,
  role,
  company,
  slug
}) => (
  <div className="col-xl-3 col-lg-3 col-md-4 col-sm-12">
    <div className="speakers xs-mb30">
      <div className="spk-img">
         <img className="img-fluid" alt="trainer-img" src={headshot[0].url}/>
        <ul>
          <li>
            <a href={twitter}>
              <i className="fa fa-twitter" />
            </a>
          </li>
          <li>
            <a href={linkedIn}>
              <i className="fa fa-linkedin" />
            </a>
          </li>
        </ul>
      </div>
      <div className="spk-info">
        <h3>
          <a href={slug} rel="noreferrer noopener" target="_blank">
            {speaker_name}
          </a>
        </h3>
        <p>{role}</p>
        <h6>{company}</h6>
      </div>
    </div>
  </div>
);

CREATING A PAGE FOR EACH SPEAKER

Gatsby is not limited to making pages from files like many static site generators.

 

Gatsby lets map your GraphQL query results to create pages.

What’s needed to create a page?

  • Part 1:  Build a “slug” for the page.

 

  • Part 2: Get data we want to create the page with.

Part 1: Build the slug with onCreateNode

exports.onCreateNode = ({ node, actions }) => {
  
  const { createNodeField } = actions;
  
  if (node.internal.type === `Airtable` && node.table === `Speakers`) {
    
    const slug = "/speakers/" + node.data.anchor
    
    createNodeField({
      node,
      name: `slug`,
      value: slug
    });
  }
};
{ id: '995475ec-7da4-538e-8232-1bf05043340c',
  table: 'Speakers',
  queryName: 'speakers',
  internal:
   { type: 'Airtable',
     contentDigest: '578c52ee6e014d486e694aa1e3f248f7',
     owner: 'gatsby-source-airtable',
     fieldOwners: { slug: 'default-site-plugin' } },
  data:
   { speaker_name: 'Leonardo Graterol',
     role: 'Web UI Engineer',
     company: 'Globant',
     twitter: 'https://twitter.com/pankas87',
     linkedIn: 'https://www.linkedin.com/in/leonardo-graterol-24863223/',
     bio: 'Leonardo is a fullstack(ish) web developer currently focused on frontend web development, working at the UI Engineering Studio of Globant.\n \n He has wide experience developing web sites and applications in several industries like e-commerce, digital marketing, GIS development companies and airlines.\n \n Leonardo is a fan of semantic HTML, good practices and web standards, and he believes in building a more accessible and inclusive online experience for everyone.',
     featured: true,
     session: [ 'recnq9psXs0kKF8X9' ],
     anchor: 'leonardo-graterol',
     order: 2,
     Sessions_copy: [ 'recm05uYtbrDu7lvO' ],
     session_track: [ 'Social Impact' ],
     session_title:
      [ 'Web Accessibility 101: Intersectional inclusion in the digital world' ],
     url: 'https://refactr.tech/detail/speakers.html#leonardo-graterol',
     session_url:
      [ 'https://refactr.tech/detail/sessions.html#web-accessibility-101-intersectional-inclusion-in-' ],
     session_anchor: [ 'web-accessibility-101-intersectional-inclusion-in-' ] },
  fields: { slug: '/speakers/leonardo-graterol' } 
}

We've extended a node to include a slug!

exports.createPages = ({ actions, graphql }) => {
  
  const { createPage } = actions;
  
  
  return graphql(

    # GraphQL query for all nodes and new field on node goes here.

  ).then(result => {
    
    # For each node of speaker data
    result.data.speakers.edges.forEach(({ node }) => {

      createPage({
        
        # Build a path using our new field on the node
        path: node.fields.slug,

        # Use this page template
        component: path.resolve(`./src/templates/the_speaker.js`),

        # Data passed to context is available
        # in page queries as GraphQL variables.
        context: {
          slug: node.fields.slug
        }
      });
    });
  });
};

creating a page

results so far...

Easier to manage.

Better experience if user is offline or has spotty internet access?

Qualifies as a progressive web app

Audit

Using Lighthouse in chrome dev tools

Lighthouse tests if your app:

  • Can load in offline or flaky network conditions
  • Is relatively fast
  • Is served from a secure origin
  • Uses certain accessibility best practices

with GatsbyJS

without GatsbyJS

How do we make refactr.tech available offline and resilient on a spotty internet connection?

How do we make refactr.tech faster?

gatsyby-config.js
module.exports = {
  siteMetadata: {
    title: "REFACTR.TECH"
  },
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `assets`,
        path: `${__dirname}/src/styles/assets/img/`
      }
    },
    {
      resolve: `gatsby-source-airtable`,
      options: {
        apiKey: process.env.GATSBY_AIRTABLE_API_KEY,
        tables: [
          {
            baseId: process.env.GATSBY_AIRTABLE_BASE_KEY,
            tableName: `Speakers`,
            queryName: `speakers`,
            mapping: { headshot: `fileNode` }
          }
        ]
      }
    },
    'gatsby-plugin-sharp',
    'gatsby-transformer-sharp'
  ]
};

How do we give refactr.tech the attributes of a progressive web app?

Text

{  
   "name":"REFACTR.TECH",
   "short_name":"REFACTR.TECH",
   "start_url":"/",
   "theme_color":"#6b37bf",
   "background_color":"#6b37bf",
   "display":"standalone",
   "icons":[  
      {  
         "src":"icons/icon-48x48.png?v=cd08a2755a01e54cfc25c889378da60f",
         "sizes":"48x48",
         "type":"image/png"
      },
   ]
}

Another audit

big improvement

without Gatsby

with Gatsby

results

Easier to manage

Better experience if user is offline or has spotty internet access

Qualifies as a progressive web app

More than doubled performance

resources

  • Gatsbyjs.org (docs & tutorials)

 

  • Gatsby Discord Community 

 

  • Gatsby channel on YouTube

thank you!

Rebuilding refactr.tech with gatsbyjs

By aliciabarrett

Rebuilding refactr.tech with gatsbyjs

  • 888