Introducción a Gatsby

1

¿Por qué Gatsby? Seguridad y Velocidad

2

¿Qué es Gatsby?

3

Diferencias entre SPA, SSR y Gatsby

Preparando el entorno

4

Requisitos previos y herramientas de desarrollo

5

Gatsby y Gatsby CLI y Starters

6

Configuración de ESLint

Fundamentos de Gatsby

7

Presentación y Estructura de Archivos de nuestro proyecto: Platziswag

8

Ecosistema de plugins

9

Usando React para manejar la parte visual e interactiva de nuestra aplicación

Creando la vista con React

10

Router en Gatsby y Componente Link

11

Layout en Gatsby

Graphql en Gatsby

12

¿Cómo funciona GraphQL en Gatsby?

13

Accediendo a nuestros datos en Gatsby desde GraphQL

14

Queries, Edges (conexiones) y Nodos en Gatsby

15

Consultas en GraphQL desde React

Usando plugins en Gatsby

16

Instalación y configuración de plugins

17

Imágenes como fuente de datos

18

Plugins de transformación

19

Estilizando nuestros componentes con styled-components

20

Estilos Globales con styled-components

Stripe checkout

21

Introducción a la API de Stripe Checkout

22

Agregando productos a nuestra tienda en línea

23

Productos en React

Generando páginas programáticamente

24

Creando páginas en función de los datos

25

Manejo de Gatsby Templates

26

Terminando la Vista de Detalle de los Productos

27

StaticQuery vs. useStaticQuery

28

Construyendo el Carrito de Compras: useContext

29

Construyendo el Carrito de Compras: Vista

30

Construyendo el Carrito de Compras: Agregar productos al carrito

31

Comprando productos

Gatsby a producción

32

Gatsby build para compilar nuestro proyecto

33

Deploy a Netlify

Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Plugins de transformación

18/33
Recursos

gatsby-transformer-sharp:

Se encarga de crear nuevas versiones de nuestras imágenes con diferentes tamaños, formatos (.webp, .png, entre otros) y calidad.

gatsby-image:

Utiliza la información de gatsby-transformer-sharp para cargar las versiones más livianas de nuestras imágenes (utilizando el tamaño y formato que mejor se adapten al usuario) y luego cambiarlas por las versiones actualizadas de mejor calidad, todo esto con el fin de mejorar el tiempo de carga inicial de nuestra aplicación.

Para usarlo solo debemos seguir los siguientes pasos:

Importar StaticQuery y graphql desde gatsby:

// src/components/image.js
import { StaticQuery, graphql } from 'gatsby';

Importar Img desde gatsby-image:

// src/components/image.js
import Img from 'gatsby-image';

Utilizar graphql para crear una consulta en la propiedad query de StaticQuery y consumir los datos desde la propiedad render:

// src/components/image.js

<StaticQuery
  query={graqhql`
    query GET_IMAGE {
      icon: file(relativePath: { eq: "icon.png" }) {
        childImageSharp {
          fluid(maxWidth: 1000) {
            ...GatsbyImageSharpFluid
          }
        }
      }
  `}
  render={data => {
    console.log(data);

    return <Img fluid={data[name].childImageSharp.fluid}/>;
  }}
/>

Aportes 19

Preguntas 3

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Debemos usar el componente StaticQuery para hacer consultas en GraphQL desde cualquier archivo o componentes que no este en la carpeta src/pages.

Hay otra forma de traer las imagenes dependiendo del nombre que obtenga como propiedad el componente.

import React from "react"
import { StaticQuery, graphql } from "gatsby"
import Img from "gatsby-image"

const Image = ({ name }) => {

  return (
    <StaticQuery
      query={
        graphql`
        query {
          allImageSharp {
            edges {
              node {
                fluid(maxWidth: 500) {
                  ...GatsbyImageSharpFluid
                  originalName
                }
              }
            }
          }
        }

      `
      }

      render={data => {
        const image = data.allImageSharp.edges.find(
          edge => {
            return edge.node.fluid.originalName === name
          }
        )

        if (!image) {
          return null
        }

        return <Img fluid={image.node.fluid} />
      }}
    />
  )
}

export default Image

obtenemos las imagenes que tenemos en el proyecto y devolvemos la que estamos necesitando por propiedad para no tener que generar una query por cada imagen que se necesite, solo se llama el componente con el nombre de la imagen y ya.

En la versión actual de Gatsby se usa el hook useStaticQuery, se puede implementar la solución que plantean los compañeros, pero se debe tener en cuenta que si tenemos muchas imágenes en nuestro sitio, se puede ver afectado el performance 👀

import React from 'react'
import { useStaticQuery, graphql } from 'gatsby'
import Img from 'gatsby-image'

const Image = ({ name }) => {
  const data = useStaticQuery(graphql`
    query GET_IMAGE {
      images: allImageSharp {
        edges {
          node {
            fluid(maxWidth: 500) {
              originalName
              ...GatsbyImageSharpFluid
            }
          }
        }
      }
    }
  `)

  const img = data.images.edges.find((edge) => edge.node.fluid.originalName.split('.')[0] === name)
  return img ? <Img fluid={img.node.fluid} /> : null
}

export default Image

Si quieren hacer un componente para cargar cualquier imagen de manera general, les dejo este componente.

import React from 'react';
import Img from 'gatsby-image';
import { StaticQuery, graphql } from 'gatsby';

function renderImage(file) {
  return <Img fluid={file.node.childImageSharp.fluid} />
}

const MyImg = function (props) {
  return <StaticQuery
    query={graphql`
      query {
      images: allFile(filter:{ extension: { regex: "/jpeg|jpg|png|gif/"}}) {
      edges {
        node {
          extension
          relativePath
          childImageSharp {
            fluid(maxWidth: 1920) {
              ...GatsbyImageSharpFluid
            }
          }
        }
      }
    }
    }
    `}
    render={({ images }) => renderImage(images.edges.find(image => image.node.relativePath === props.src))}
  />
}
export default MyImg;

Para usarlo solo necesitan pasar como de prop la ruta relativa de su imagen.

<MyImg src={relativePath} />

Hola!!!
A los usuarios de Mac les muestra el error de la imagen (33% Generating image thumbnails
ERROR)
. Lo solucione ejecutando este comando rm -rf node_modules y luego volver a instalar: npm install.

Ocupando gatsby-plugin-image

import React from "react"
import { graphql, useStaticQuery } from "gatsby"
import { GatsbyImage, getImage } from "gatsby-plugin-image"

const Image = ({ name, alt }) => {
  const data = useStaticQuery(graphql`
    query {
      icon: file(relativePath: { eq: "icon.png" }) {
        childImageSharp {
          gatsbyImageData(
            width: 200
            placeholder: BLURRED
            formats: [AUTO, WEBP, AVIF]
          )
        }
      }
    }
  `)
  return (
    <GatsbyImage image={getImage(data[name].childImageSharp)} alt={alt ?? ""} />
  )
}

export default Image

Usando hooks para traer la imagen.

import React from 'react';
import { graphql, useStaticQuery } from 'gatsby';
import Img from 'gatsby-image';

export default function Image({ name }) {
    const data = useStaticQuery(graphql`query {
        icon: file(relativePath: {eq: "icon.png"}) {
            childImageSharp {
                fluid(maxWidth: 500) {
                    ...GatsbyImageSharpFluid
                }
            }
        }
    }`);
    return (<Img fluid={data[name].childImageSharp.fluid} />);
};```

Por cierto, si no te funciona el ctrl + space, para ver las opciones en GraphiQL.
A mi me funciona usando option + space.

Actualmente este método para las imágenes ya no se utiliza en Gatsby, ya que en la misma página indica que está obsoleto.

Ahora se utiliza “StaticImage”

https://www.gatsbyjs.com/docs/how-to/images-and-media/using-gatsby-plugin-image

Así me que un componente con gatsby-plugin-image, paso como props image=“nombre.jpg” y alt=“algo”, con esto puedo usar este componente para toda la imágenes.

import React from "react"
import { useStaticQuery, graphql } from "gatsby"
import { GatsbyImage, getImage } from "gatsby-plugin-image"

const ImageComponent = (props) => {

   const imageQuery = useStaticQuery(graphql`query{
	allFile(filter: {ext: {regex: "/(jpg)|(png)/"}}) {
	   edges {
	      node {
	         base
                 childImageSharp {
                    gatsbyImageData(transformOptions: {fit: CONTAIN})
                 }
              }
           }
        }
     }`)

   const data = imageQuery.allFile.edges.find(edge => {
      return edge.node.base === props.image
   })

   const image = getImage(data.node)

   return (
      <GatsbyImage image={image} alt={props.alt}/>
   )
}

export default ImageComponent

Así quedan los plugins de gatsby-config.js

plugins: [
   `gatsby-plugin-image`,
   `gatsby-transformer-sharp`,
   {
      resolve: `gatsby-plugin-sharp`,
      options: {
         defaults: { 
            quality: 100,
            placeholder: `blurred`,
         },
      }
   },
   {
      resolve: `gatsby-source-filesystem`,
      options: {
         name: `images`,
         path: `${__dirname}/src/images`,
      },
   },
],

Les recomiendo que le echen un ojo a este nuevo plugin de gatsby.
gatsby-plugin-image

Por lo que veo, el codigo que nos dice Joss(el profesor) tiene un funcionamiento extraño (el cual nos da un error): El callback “data” recibe dos o tres llamados seguidos en vez de solo uno(puedes probarlo con un console.log(data)), el primero llega correctamente siendo la variable name = icon, sin embargo, el segundo llega como name = undefined, por esto saca el error en el navegador “TypeError: Cannot read property ‘childImageSharp’ of undefined”. Pude encontrar la solucion a este problema.
La solucion para esto es la siguiente: cambia un poco el codigo pero logramos exactamente el mismo objetivo que es renderizar una sola imagen de forma “fluida”. No pasamos el parametro name como prop, si no, usamos el mismo server de GrapQL para traenos la imagen que queremos asi:

jumbo.js

import React from "react"
import { StyledJumbo } from "../styles/components"
import Image from "./image.js"

export default function Jumbo({ description }) {
  return (
    <StyledJumbo>
      <div>
        <h2>Consigue el mejor swag exclusivo y especial de Platzi</h2>
        <small>{description}</small>
      </div>
      <Image />
    </StyledJumbo>
  )
}

image.js

export default function Image() {
  return (
    <StaticQuery
      query={graphql`
        query GET_IMAGE {
          icon: file(relativePath: { eq: "icon.png" }) {
            childImageSharp {
              fluid(maxWidth: 1000) {
                ...GatsbyImageSharpFluid
              }
            }
            name
          }
        }
      `}
      render={data => (
        <Img fluid={data[data.icon.name].childImageSharp.fluid} />
      )} //data llega como callback
    />
  )
}

Espero les sirva bastante!

A mi como usuario que la imagen tarde en cargar me da la sensación de lentitud.
Y de momento las queries son horribles. Demasiada dot notation.
Espero que mejore luego.

Si no te funciona el código del profesor en GraphiQL, prueba con este:

{
	allImageSharp {
    edges {
      node {
        fluid(maxWidth: 500) {
          src
          srcWebp
          sizes
          originalImg
          base64
        }
      }
    }
  }
}

Existe un problema: el atributo fluid se reusa a identificar al prop llamado “name”

Estoy siguiendo con las instrucciones y me esta generando el siguiente error

TypeError: Cannot read property ‘childImageSharp’ of undefined
render
src/components/image.js:19
16 | }
17 | }
18 | `}

19 | render={data => <Img fluid={data[name].childImageSharp.fluid} />}
20 | />
21 | )
22 | }

según pude ver la forma cambio:
https://www.gatsbyjs.org/tutorial/gatsby-image-tutorial/#image-fragments

pero no se como implementarlo

Tenía este error al agregar la imagen

TypeError: Cannot read property 'childImageSharp' of undefined

Para solucionarlo cambié el valor del atributo del componente Image en Jumbo.js; en vez de “icon” debería ser “logo”

import React from "react"
import { StyledJumbo } from "../styles/components"
import { Image } from "./"

export default function Jumbo({ description }) {
  return (
    <StyledJumbo>
      <div>
        <h2>¡Consigue el mejor swag exclusivo y especial de platzi!</h2>
        <small>{description}</small>
      </div>
      <Image name="logo" />
    </StyledJumbo>
  )
}

A alguien más le pasa que el query no funciona?

<StaticQuery
  query={graphql`
    query GET_IMAGE {
      icon: file(relativePath: { eq: "icon.png" }) {
        childImageSharp {
          fluid(maxWidth: 1000) {
            ...GatsbyImageSharpFluid
          }
        }
      }
  `}
  render={data => {
    console.log(data);

    return <Img fluid={data[name].childImageSharp.fluid}/>;
  }}
/>

Output

- Unknown field 'fluid' on type 'ImageSharp'. 
      file: /Users/behar/git/platzi/frontend/gatsby/Gatsby-platzi/src/components/image.js

El render también se puede realizar asi:

render={data => {
        console.log(data)

        return <Img fluid={data.icon.childImageSharp.fluid} />
      }}