Acabas de copiar mí email en tu portapapeles

10 de July 2019

Portfolio + Blog con React, Gatsby y Sanity. (Parte 1)

Gatsby + Sanity (Primera Parte)

Mi nombre es Sebastián Tamashiro. Soy desarrollador front-end, diseñador de interacciones y actualmente trabajo en Avantrip.

Hasta marzo del 2019 mi portfolio estaba hecho en HTML, CSS, un poco de JavaScript y PHP. Pero al momento de entrar a trabajar aprendí React.js y me focalicé en aprender más a fondo JavaScript.

Hoy, después de varios meses publico la nueva versión de mi portfolio basado en React.js, utilizando Gatsby.js y Sanity.io como headlesss CMS.

En este post mi intención es transmitir todos los conocimientos básicos que debes tener para poder lanzarte a desarrollar tu propio portfolio, blog, o lo que quieras utilizando estas herramientas.

Hay algunas cosas que no voy a explicar porque sino el post se volvería eterno. Para poder seguir este tutorial debes:

  • Tener conocimientos en React.js
  • Tener conocimientos en JavaScript ES6

Este artículo está dividido en 2 partes. En esta primera parte voy a hablar sobre Gatsby, y en la segunda parte de Sanity, el cual te dejo el link a continuación por si querés saltearte esta parte. [Segunda Parte]

Cualquier duda que tengas, podés enviarme un mensaje por Twitter. ¡Me encantaría recibir tu feedback para poder mejorar en el futuro!

¿Qué es Gatsby?

Gatsby es un framework basado en React para crear sitios web y aplicaciones de forma estática de una manera fácil y rápida. Sigue la estructura JAMStack, la cuál en resumidas palabras utiliza JavaScript, APIy Markup para crear webs modernas. Algo muy interesante que tiene este framework es la incorporación de GraphQL para hidratar los componentes que tengamos.

Para iniciar un nuevo proyecto con Gatsby hay que instalar primero el CLI ejecutando el comando en la terminal:

npm install -g gatsby-cli

Una vez hecho esto, creamos un sitio nuevo utilizando el boilerplate que nos ofrece Gatsby.

gatsby new nuevo-sitio-con-gatsby
cd nuevo-sitio-con-gatsby
npm install
gatsby develop

Al terminar, se nos va a abrir una ventana en el navegador en localhost:8000. Felicidades! Ya levantaste tu primera página hecha con Gatsby

Cosas a tener en cuenta

Cuando trabajamos con Gatsby ya hay varias cosas que pasan automágicamente. A continuación voy a mencionar algunas de esas cosas que fui descubriendo cuando estaba desarrollando mi sitio.

Routing de paginas

Si queremos generar páginas estáticas lo que debemos hacer es crear es un archivo con el nombre que queremos que tenga la URL. Es decir que, si queremos tener por ejemplo /about, nuestro archivo debe llamarse about.js.

Solamente puede hacer un index.js por carpeta. Es decir que si queremos podemos tener la siguientes estructuras.

|-- /pages
	|-- contact.js
	|-- about.js
	|-- blog.js
	|-- index.js
|-- /pages
	|-- /contact
		|-- index.js
	|-- /about
		|-- index.js
	|-- /blog
		|-- index.js
	|-- index.js

GraphQL

Si tenemos que hacer una query, lo ideal es hacerla con GraphQL. Gatsby esta muy integrado con esta herramienta y casi todos los plugins que vamos a encontrar que le pegan a una API unifican los datos de esta fuente con GraphQL.

Query variables

Generalmente cuando trabajamos con GraphQL utilizamos ApolloProvider como un HOC(High Order Components), el cual esta por arriba de toda nuestra web/aplicación. Pero cuando estamos usando Gatsby no es necesario, ya esta implícito de nuestro código y no nos tenemos que preocupar por colocarlo.

Pongamos un ejemplo, tenemos un post el cuál tiene que recibir un título, el thumbnail, la categoría y el cuerpo del artículo. Debería quedar algo así usando React Hooks:

import React from 'react';

const Post = ({ title, category, thumbnail, body }) => {
	return(
		<h1>{title}</h1>
		<small>{category}</small>
		<figure>
			<img src={thumbnail} />
		</figure>
		<main>{body}</main>
	)
}

export default Post;

Con ApolloProvider

Si queremos que reciba dinámicamente estas propiedades según el ID del post. Lo que deberíamos hacer con ApolloProvider es algo así:

import React from 'react';
import { Query } from "react-apollo";

const GET_POST = gql`
	{
		query Post($id: String) {
			blog(id: {eq: $id}) {
				title
				category
				thumbnail
				body
			}
		}	
	}
`;

const Content = ({ id }) => (
	<Query query={GET_POST} variables={{ id }}>
		{({ loading, error, data }) => {
      if (loading) return null;
      if (error) return `Error! ${error}`;

      return (
        <div>
					<h1>{data.blog.title}</h1>
					<small>{data.blog.category}</small>
					<figure>
						<img src={data.blog.thumbnail} />
					</figure>
					<main>{data.blog.body}</main>
				</div>
      );
    }}
	</Query>
)

const Post = () => {
	return(
		<Content />
	)
}

export default Post;

Con Gatsby

Pero con Gatsby nos evitamos crear la constante Content que va a escuchar la query GET_POST y dentro de esta, la variable id.

Lo que tenemos que hacer para lograrlo es primero crear una página que va a funcionar como template para nuestra información extraída de GraphQL. Por ejemplo, en mi caso tuve que hacer esto:

// gatsby-node.js
exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions

  const result = await graphql(`
    query allPostQuery {
      allSanityBlog {
        edges {
          node {
            slug {
              current
            }
            id
          }
        }
      }
    }
  `)

  if (result.errors) {
    throw result.errors
  }

  const posts = result.data.allSanityBlog.edges || []
  posts.forEach(edge => {
    const id = edge.node.id
    const path = `/blog/${edge.node.slug.current}`

    createPage({
      path,
      component: require.resolve("./src/pages/post.js"),
      context: { id },
    })
  })
}


Expliquemos esto por partes:

createPage es la API que nos provee Gatsby para decirle que queremos crear una página de forma dinámica. Hay muchas más, que si te interesa podes ver en la documentación.

IMPORTANTE: Los procesos que corren dentro de gatsby-node.js ocurren únicamente al momento de hacer el build de la página, por lo que si hacemos un cambio en la estructura del template debemos tirar el sitio abajo y volverlo a levantar.

const result = await graphql(`
    query allPostQuery {
      allSanityBlog {
        edges {
          node {
            slug {
              current
            }
            id
          }
        }
      }
    }
  `)

El código de arriba es la query que hice para pedirle a Gatsby que me busque dentro de todos los posts que escribí y extraiga el slug y el ID del mismo.

const posts = result.data.allSanityBlog.edges || []
posts.forEach(edge => {
    const id = edge.node.id,
			    path = `/blog/${edge.node.slug.current}`

    createPage({
      path,
      component: require.resolve("./src/pages/post.js"),
      context: { id },
    })
  })

Ahora, por cada uno de los resultados de esa query, le pido que separe el id, y el slug; y que los guarde en las constantes id y path. Después, que cree una página con la ruta que definimos en la variable path, utilizando el template que esta en esta ruta ./src/pages/post.js y que deje el id como contexto.

Si todo salió bien, dentro del archivo post.js deberías haber, haciendo console.log, una prop llamada 'pageContext' y dentro una prop llamada id.

Una vez hecho esto, ¡Felicidades! Ya pasaste una variable de una query a una página creada dinámicamente. Ahora lo que nos queda es popular nuestro componente con la data de nuestra query, haciendo unas pequeñas modificaciones.

import React from 'react';

const Post = ({ data }) => {
	return(
		<h1>{data.posts.title}</h1>
		<small>{data.posts.category}</small>
		<figure>
			<img src={data.posts.thumbnail} />
		</figure>
		<main>{data.posts.body}</main>
	)
}

export default Post;

Ya no vamos a esperar todas las propiedades de antes porque todas esas viajan dentro de data en forma de array.

Conclusión

En el artículo vimos cómo crear nuestro primer sitio con Gatsby, crear páginas estáticas y páginas dinámicas con contenido proveniente de GraphQL. En la segunda parte de este artículo (Al que podes acceder si haces click acá) vamos a ver cómo crear un proyecto en Sanity.io y cómo customizarlo a nuestro gusto.

Para seguir leyendo la segunda parte de este artículo podes hacer click acá