Debemos usar el componente StaticQuery
para hacer consultas en GraphQL desde cualquier archivo o componentes que no este en la carpeta src/pages
.
Introducción a Gatsby
¿Por qué Gatsby? Seguridad y Velocidad
¿Qué es Gatsby?
Diferencias entre SPA, SSR y Gatsby
Preparando el entorno
Requisitos previos y herramientas de desarrollo
Gatsby y Gatsby CLI y Starters
Configuración de ESLint
Fundamentos de Gatsby
Presentación y Estructura de Archivos de nuestro proyecto: Platziswag
Ecosistema de plugins
Usando React para manejar la parte visual e interactiva de nuestra aplicación
Creando la vista con React
Router en Gatsby y Componente Link
Layout en Gatsby
Graphql en Gatsby
¿Cómo funciona GraphQL en Gatsby?
Accediendo a nuestros datos en Gatsby desde GraphQL
Queries, Edges (conexiones) y Nodos en Gatsby
Consultas en GraphQL desde React
Usando plugins en Gatsby
Instalación y configuración de plugins
Imágenes como fuente de datos
Plugins de transformación
Estilizando nuestros componentes con styled-components
Estilos Globales con styled-components
Stripe checkout
Introducción a la API de Stripe Checkout
Agregando productos a nuestra tienda en línea
Productos en React
Generando páginas programáticamente
Creando páginas en función de los datos
Manejo de Gatsby Templates
Terminando la Vista de Detalle de los Productos
StaticQuery vs. useStaticQuery
Construyendo el Carrito de Compras: useContext
Construyendo el Carrito de Compras: Vista
Construyendo el Carrito de Compras: Agregar productos al carrito
Comprando productos
Gatsby a producción
Gatsby build para compilar nuestro proyecto
Deploy a Netlify
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
No se trata de lo que quieres comprar, sino de quién quieres ser. Aprovecha el precio especial.
Antes: $249
Paga en 4 cuotas sin intereses
Termina en:
José Carlos Correa Mandujano
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
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} />
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} />);
};```
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.
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
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
Por cierto, si no te funciona el ctrl + space, para ver las opciones en GraphiQL.
A mi me funciona usando option + space.
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} />
}}
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?