Skip to main content

12. Gatsby


Gatsby Notes

Overview

  • Static site generator

  • Built on React

  • Have powerful configurations like code-splitting, faster page loads, SSR, assets and images optimization, service workers, and prefetching.

  • npm i -g gatsby-cli

  • gatsby new <project_name> [<starter>]

  • if a starter is omitted, a default gatsby starter will be provided.

  • or follow one of the starter applications on the gatsby website using the starter option.

  • Hello world starter: https://github.com/gatsbyjs/gatsby-starter-hello-world

  • yarn start or gatsby develop,

  • two urls: 8000 and 8000/___graphql with graphql_playground

  • Folder structure

  • .cache => leave it, auto-generated by gatsby develop/build and removed via gatsby clean

  • node_modules

  • public folder => our production application(dist or build folder in react!, I know in react public folder was for index and manifest files but in gatsby, it is a build directory), automatically generated via gatsby build(use public folder to deploy your website).

  • static folder @rootofproject holds our assets, images, fonts, and CSS files... but it is not recommended because when files are added in the static folder they straightaway go into the public folder on running build and hence avoiding any optimizations, you would rather do actual imports with import/export and add assets in let's say assets folder in src directory(or it can be static folder but this time inside src folder!).

Creating Pages

  • create a pages directory in src and add js files and the filename will be the URL of that page.
  • add at least index.js to be worked as index.html!
  • Navigation b/w pages using Link available in gatsby (internally reach-router) for SPA.
  • import {Link} from 'gatsby'

Styling

  • inline style={{color: "red"}}
  • external css files and import './filename.css', Problem: Name collisions.
  • CSS Modules - Good solution
    • filename.module.css
    • import styled from "filename.module.css"
    • add style via className={styles.title}
  • Bootstrap
    • npm install bootstrap
    • import 'bootstrap/dist/css/bootstrap.min.css' inside layout.js to add to every page. so in react apps, add it in App.js.
    • and use container, row, col-12...
  • SASS
    • required gatsby plugin wheee!
    • search for sass at the gatsby website in the plugin section, and you will get gatsby-plugin-sass
    • npm install node-sass gatsby-plugin-sass and follow the steps from the website.
    • Note: It requires changing gatsby-config.js file and every time you make changes to the config file, always restart the development server.
    • create a gatsby-config.js file if not already available at the root of the project.
      • after making changes. import './filename.scss'
  • SASS Modules - The best solution
    • works just like CSS modules just change in extension from CSS to SCSS(need to add sass plugin as above).
  • CSS in JS (Styled Component) Best solution but everyone likes it
    • add styled component plugin, gatsby-plugin-styled-components, npm install gatsby-plugin-styled-components styled-components babel-plugin-styled-components
    • import styled from " styled-components"
    • const something = styled.div``(tag template literal);
    • add vscode-styled-compoents extension for good experience.

Gatsby using Graphql

  • working with data (Gatsby DataLayer).

  • loading data into react components via <StaticQuery> or pageQuery after trying query in graphiQL.(8000/___graphql).

  • data can be from API, Headless CMS, JSON, Markdown, siteMetaData, and we can use graphql to get this data, type of data,

  • Page Query is used only in pages and we can pass variables in page-query.

  • Static Query can be used in pages as well as other as well, but variables can not be passed in static query.

  • Graphql queries have fields and fields with arguments (mutations).

{
field(arg: "value") {
subfield
}
}
  • gatsby config file only accepts certain keys so can't just put your defined key there. the ex- data key is not allowed whereas site metadata is allowed because of gatsby internal plugin for SEO(so get more graphql files by installing more and more plugins!).
  • <StaticQuery query={query} render={(data)=>{return (JSX using data)}}/>, useStaticQuery(graphqlquery)
  • render={function} is render-props concept
  • pageQuery is a concept of exporting a graphql query from a page component and accessing data via props passed to the page component, no separate hook or component like <PageQuery/> exist.
  • routing is automatically coming up with gatsby that's why we have a Link from gatsby and by default, all the props to pages components(files inside page folder) have a path, navigate, URL, location props available by default.
  • In-page components if you export a graphql query, it is resolved and data is available as props property in component., accessible via props.data

Gatsby optimization

  • Image Optimization

    • Plugin1: gatsby-source-filesystem npm i gatsby-source-filesystem, it gives us two queries allFile and file, where all file returns all the files in a folder set up in config file and the file takes arguments to figure out which specific file you want.

      plugins: [
      {
      resolve: 'gatsby-source-filesystem',
      options: {
      name: images,
      path: `${__dirname}/src/images`,
      },
      },
      {
      resolve: 'gatsby-source-filesystem',
      options: {
      name: fonts,
      path: `${__dirname}/src/fonts`,
      },
      },
      ];
      • use of name property we set in the config file

        • let's say we set two folders images and fonts, now to access only fonts folder files, we use that name property to filter as sourceInstanceName
        query {
        allFile(filter: { sourceInstanceName: { eq: "fonts" } })
        }
    • Plugin2: gatsby-image npm i gatsby-image gatsby-transformer-sharp gatsby-plugin-sharp

      • find the image via gatsby-source-filesystem that you want to optimize and add lazy loading, blur effects
      • how? via allFile or file, discussed just above
      • since we have installed gatsby-image we get two options fixed(fixed width image for all devices) and fluid(dynamic width for different devices, internally uses html picture, source, and srcset tags and add image urls with screen-width) in graphql query.
      • It also provides a React Component that takes fixed or fluid props with values generated from graphql query.
        • import Img from 'gatsby-image'
        • <Img fixed={props.data.exampleFixed.childImageSharp.fixed}>
        • <Img fluid={props.data.exampleFluid.childImageSharp.fluid}>
      • with query
      {
      exampleFixed: file(relativePath: { eq: "image.png" }) {
      childImageSharp{
      fixed(width:400, height: 400){
      ...GatsbyImageSharpFixed # It does not work in playground so add that to project, but to check if this query is working or not add any dummy field like src, size instead of ...SomeFragmentfromDocs, copy paste and remove dummy field with one of Fragments on docs website.
      }
      }
      }
      exampleFluid: file(relativePath: { eq: "image2.png" }) {
      childImageSharp{
      fluid {
      srcSet
      ...GatsbyImageSharpFluid
      }
      }
      }
      }```

      - Fragments are important here as they have the optimizations/very-less-file-size/effects/lazy-loading-on-slow-network/loading-only-when-image-in-view e.t.c.

More Data(ContentFul, Headless CMS, JSON, markdown)

MDX to pages

Plugin: gatsby-mdx

frontmatter:

Questions

  • SCSS Modules - filename.module.scss?, required? Does it works like that? It would be cool if it does.

    • Ans: No need just give your component topmost container an id and in scss file start with:
    #id {
    h1 {
    table {
    thead {
    /// and so on...
    }
    }
    }
    }

There will never be the name collision problem.