
Como você sabe, você não pode ir muito longe em alguns clichês, então você precisa se aprofundar em qualquer tecnologia para aprender a escrever algo que vale a pena. Este artigo discute os detalhes do Gatsby.js , cujo conhecimento permitirá criar e manter sites e blogs complexos.
Artigo anterior sobre como criar e publicar um blog pessoal usando JAM-stack
Tópicos discutidos abaixo:
Preparação
Instale o Gatsby no PCyarn global add gatsby-cli
Clonando um projeto mínimo npx gatsby new gatsby-tutorial https://github.com/gatsbyjs/gatsby-starter-hello-world cd gatsby-tutorial
Inicialização do Repositório git init git add . git commit -m "init commit"
Verificação de integridade yarn start
Se não houver erros no console e no navegador ao longo do caminho http: // localhost: 8000, você verá "Olá, mundo!" isso significa que tudo está funcionando corretamente. Você pode tentar alterar o conteúdo do arquivo /src/pages/index.js para verificar a atualização a quente.
Estrutura e roteamento da página
Para criar uma página no Gatsby, basta colocar o novo arquivo na pasta / src / pages e ele será compilado em uma página HTML separada. É importante observar que o caminho para esta página corresponderá ao caminho real com o nome . Por exemplo, adicione mais algumas páginas:
src └── pages ├── about.js ├── index.js └── tutorial ├── part-four.js ├── part-one.js ├── part-three.js ├── part-two.js └── part-zero.js
O conteúdo ainda não é importante, portanto, qualquer texto pode ser usado para distinguir entre as páginas.
import React from "react"; export default () => <div>Welcome to tutorial/part-one</div>;
Verifique no navegador:
Dessa maneira, ao estruturar arquivos, você pode resolver imediatamente os problemas de roteamento.
Há também uma API createPage especial com a qual você pode controlar de maneira mais flexível os caminhos e os nomes das páginas, mas para trabalhar com ela, precisamos entender como os dados funcionam no Gatsby, portanto, consideraremos um pouco mais no artigo.
Combine as páginas criadas usando os links. Para isso, usamos o componente <Link />
do pacote Gatsby, criado especificamente para navegação interna. Para todos os links externos, use a tag <a>
regular.
/src/pages/index.js
import React from "react"; import { Link } from "gatsby"; export default () => ( <div> <ul> <li> <Link to="/about">about</Link> </li> <li> <Link to="/tutorial/part-zero">Part #0</Link> </li> <li> <Link to="/tutorial/part-one">Part #1</Link> </li> <li> <Link to="/tutorial/part-two">Part #2</Link> </li> <li> <Link to="/tutorial/part-three">Part #3</Link> </li> <li> <Link to="/tutorial/part-four">Part #4</Link> </li> </ul> </div> );
<Link>
oculto possui um mecanismo muito complicado para otimizar o carregamento da página e, portanto, é usado em vez de <a>
para navegar no site. Mais detalhes podem ser encontrados aqui .

As páginas são criadas, os links são adicionados, e a navegação está concluída.
Componentes, modelos e sua interação
Como você sabe, em qualquer projeto sempre há elementos repetidos; para sites, é um cabeçalho, rodapé, barra de navegação. Além disso, as páginas, independentemente do conteúdo, são criadas de acordo com uma certa estrutura e, como o Gatsby é um compilador do React , a mesma abordagem de componente é usada para resolver esses problemas.
Crie os componentes para o cabeçalho e o painel de navegação:
/src/components/header.js
import React from "react"; import { Link } from "gatsby"; /** * * , React-. * , * " ". * "" GraphQL gatsby- */ import logoSrc from "../images/logo.png"; export default () => ( <header> <Link to="/"> <img src={logoSrc} alt="logo" width="60px" height="60px" /> </Link> That is header </header> );
/src/components/sidebar.js
import React from "react"; import { Link } from "gatsby"; export default () => ( <div> <ul> <li> <Link to="/about">about</Link> </li> <li> <Link to="/tutorial/part-zero">Part #0</Link> </li> <li> <Link to="/tutorial/part-one">Part #1</Link> </li> <li> <Link to="/tutorial/part-two">Part #2</Link> </li> <li> <Link to="/tutorial/part-three">Part #3</Link> </li> <li> <Link to="/tutorial/part-four">Part #4</Link> </li> </ul> </div> );
e adicione-os a /src/pages/index.js
import React from "react"; import Header from "../components/header"; import Sidebar from "../components/sidebar"; export default () => ( <div> <Header /> <Sidebar /> <h1>Index page</h1> </div> );
Verificamos:

Tudo funciona, mas precisamos importar o cabeçalho e a barra lateral em cada página separadamente, o que não é muito conveniente. Para resolver esse problema, basta criar um componente de layout e agrupar cada página.
Layout de Gatsby == reagir contêiner
sim, não é uma igualdade estrita, porque é "quase" a mesma coisa
/src/components/layout.js
import React from "react"; import Header from "./header"; import Sidebar from "./sidebar"; export default ({ children }) => ( <> <Header /> <div style={{ margin: `0 auto`, maxWidth: 650, backgroundColor: `#eeeeee` }} > <Sidebar /> {children} </div> </> );
/src/pages/index.js (e todas as outras páginas)
import React from "react"; import Layout from "../components/layout"; export default () => ( <Layout> <h1>Index page</h1> </Layout> );
Feito, olhe para o navegador:

Por que o projeto tem todos os nomes de arquivo com uma letra minúscula? Para começar, vamos determinar que o namespace para React vem do fato de "todo arquivo é uma classe e a classe sempre é maiúscula". No Gatsby, os arquivos ainda contêm classes, mas existe um "mas" - "cada arquivo é uma página em potencial e seu nome é o URL dessa página". A comunidade chegou à conclusão de que links como http://domain.com/User/Settings
não são comme-il-faut e kebab-case aprovado para nomes de arquivos.
Estrutura de arquivo src ├── components │ ├── header.js │ ├── layout.js │ └── sidebar.js ├── images │ └── logo.png └── pages ├── about.js ├── index.js └── tutorial ├── part-eight.js ├── part-five.js ├── part-four.js ├── part-one.js ├── part-seven.js ├── part-six.js ├── part-three.js ├── part-two.js └── part-zero.js
Trabalhar com dados
Agora que a estrutura do site está pronta, você pode prosseguir para o preenchimento do conteúdo. A abordagem clássica de "código rígido" não se adequava aos criadores da pilha JAM, além de "renderizar conteúdo de solicitações AJAX" e, portanto, sugeriram preencher os sites com conteúdo em tempo de compilação. No caso do Gatsby , o GraphQL é responsável por isso, o que facilita o trabalho com fluxos de dados de qualquer fonte.
É impossível falar sobre o GraphQL em poucas palavras, por isso é aconselhável estudá-lo você mesmo ou aguardar meu próximo artigo. Você pode ler mais sobre como trabalhar com o GraphQL aqui .
Para trabalhar com o GraphQL , a partir da segunda versão, o pacote gatsby
possui um componente gatsby
que pode ser usado nas páginas e em componentes simples, e essa é sua principal diferença em relação à consulta da página anterior . Até o momento, nosso site não está conectado a nenhuma fonte de dados, portanto, tentemos exibir os metadados da página, por exemplo, e depois passar para coisas mais complexas.
Para criar uma query
é necessário abrir http: // localhost: 8000 / ___ graphql e usar a barra lateral com a documentação para encontrar os dados disponíveis sobre o site e não se esqueça do preenchimento automático.

/src/components/sidebar.js
import React from "react"; import { Link, StaticQuery, graphql } from "gatsby"; export default () => ( <StaticQuery query={graphql` { allSitePage { edges { node { id path } } } } `} render={({ allSitePage: { edges } }) => ( <ul> {edges.map(({ node: { id, path } }) => ( <li key={id}> <Link to={path}>{id}</Link> </li> ))} </ul> )} /> );
Agora, usando a query
obtemos dados sobre as páginas que renderizamos no painel de navegação e não precisamos nos preocupar com o fato de o link não corresponder ao nome, porque todos os dados são coletados automaticamente.

De fato, esses são todos os dados que podem estar em nosso site sem o uso de plug-ins de terceiros e sem o bom e antigo "hardcode"; portanto, passamos sem problemas ao próximo tópico do nosso artigo - plugins.
Plugins
Na sua essência, Gatsby é um compilador com um monte de guloseimas, que são plugins. Utilizando-os, você pode personalizar o processamento de determinados arquivos, tipos de dados e vários formatos.
Crie o arquivo /gatsby-config.js no nível raiz do aplicativo. responsável pela configuração do compilador como um todo e tente configurar o primeiro plug-in para trabalhar com arquivos:
Instalação do plugin:
yarn add gatsby-source-filesystem
Configuração no arquivo /gatsby-config.js:
module.exports = { plugins: [ { resolve: `gatsby-source-filesystem`, options: { name: `images`, path: `${__dirname}/src/images/`, } } ], }
Mais detalhes sobre o arquivo acima /** * gatsby-config.js * JS * */ module.exports = { /** * 'plugins' pipeline * , */ plugins: [ /** * , * */ `gatsby-example-plugin`, { resolve: `gatsby-source-filesystem`, options: { name: `images`, path: `${__dirname}/src/images/`, } } ], }
Lembra-se de que conversamos sobre a importação "correta" de imagens para o Gatsby ?
/src/components/header.js
import React from "react"; import { Link, StaticQuery, graphql } from "gatsby"; export default () => ( <StaticQuery query={graphql` { allFile(filter: { name: { eq: "logo" } }) { edges { node { publicURL } } } } `} render={({ allFile: { edges: [ { node: { publicURL } } ] } }) => ( <header> <Link to="/"> <img src={publicURL} alt="logo" width="60px" height="60px" /> </Link> That is header </header> )} /> );
Nada mudou no site, mas agora a imagem é substituída usando o GraphQL, em vez de uma simples importação de webpack. À primeira vista, pode parecer que os designs são muito complexos e foram gestos desnecessários, mas não vamos tirar conclusões precipitadas, porque a coisa está nos mesmos plugins. Por exemplo, se decidíssemos postar milhares de fotos no site, em qualquer caso, teríamos que pensar em otimizar o carregamento de todo o conteúdo e, para não criar nosso processo de carregamento lento a partir do zero, basta adicionar um plug - in gatsby-image que otimize o carregamento de todos imagens importadas usando a query
.
Instalando plug-ins para estilizar:
yarn add gatsby-plugin-typography react-typography typography typography-theme-noriega node-sass gatsby-plugin-sass gatsby-plugin-styled-components styled-components babel-plugin-styled-components
gatsby-config.js
module.exports = { plugins: [ { resolve: `gatsby-source-filesystem`, options: { name: `images`, path: `${__dirname}/src/images/` } }, // add style plugins below `gatsby-plugin-typography`, `gatsby-plugin-sass`, `gatsby-plugin-styled-components` ] };
No site oficial, você pode encontrar um plugin para todos os gostos.
Estilo de aplicativo
Vamos começar a estilizar o aplicativo usando várias abordagens. Na etapa anterior, já instalamos plug-ins para trabalhar com o SASS , os componentes com estilo e a biblioteca typography.js , embora seja importante observar que o css.modules é suportado imediatamente.
Vamos começar com os estilos globais, que, como outras coisas relacionadas ao site inteiro, devem ser configurados no arquivo /gatsby-browser.js :
import "./src/styles/global.scss";
Mais sobre gatsby-browser.js
/src/styles/global.scss
body { background-color: lavenderblush; }
Por várias razões, as tendências dos últimos anos estão inclinadas para a abordagem "CSS em JS", portanto você não deve abusar dos estilos globais e é melhor limitar-se a indicar a fonte e as classes reutilizadas. Este projeto em particular planeja usar o Typography.js para esses fins, para que os estilos globais permaneçam vazios.
Você pode ter notado alterações na aparência do site após adicionar a gatsby-plugin-typography
à configuração - isso ocorre porque a predefinição padrão foi aplicada e agora vamos configurá-la por nós mesmos.
/src/utils/typography.js
import Typography from "typography"; import theme from "typography-theme-noriega"; const typography = new Typography(theme); export default typography;
Você pode selecionar qualquer outra predefinição da lista ou criar sua própria usando a API do pacote ( exemplo da configuração do site oficial do Gatsby)
/gatsby-config.js
module.exports = { plugins: [ { resolve: `gatsby-source-filesystem`, options: { name: `images`, path: `${__dirname}/src/images/` } }, { resolve: `gatsby-plugin-typography`, options: { pathToConfigModule: `src/utils/typography` } }, `gatsby-plugin-sass`, `gatsby-plugin-styled-components` ] };
E, dependendo da predefinição selecionada, o estilo global do site será alterado. Decida qual abordagem definir estilos globais para si mesmo, é uma questão de preferências e diferenças pessoais do ponto de vista técnico, mas passamos aos componentes de estilo usando componentes de estilo :
Adicione um arquivo com variáveis globais /src/utils/vars.js
export const colors = { main: `#663399`, second: `#fbfafc`, main50: `rgba(102, 51, 153, 0.5)`, second50: `rgba(251, 250, 252, 0.5)`, textMain: `#000000`, textSecond: `#ffffff`, textBody: `#222222` };
/src/components/header.js import React from "react"; import { Link, StaticQuery, graphql } from "gatsby"; import styled from "styled-components"; import { colors } from "../utils/vars"; const Header = styled.header` width: 100%; height: 3em; display: flex; justify-content: space-between; align-items: center; background-color: ${colors.main}; color: ${colors.textSecond}; padding: 0.5em; `; const Logo = styled.img` border-radius: 50%; height: 100%; `; const logoLink = `height: 100%;`; export default () => ( <StaticQuery query={graphql` { allFile(filter: { name: { eq: "logo" } }) { edges { node { publicURL } } } } `} render={({ allFile: { edges: [ { node: { publicURL } } ] } }) => ( <Header> That is header <Link to="/" css={logoLink}> <Logo src={publicURL} alt="logo" /> </Link> </Header> )} /> );
/src/components/sidebar.js import React from "react" import { Link, StaticQuery, graphql } from "gatsby" import styled from "styled-components" import { colors } from "../utils/vars" const Sidebar = styled.section` position: fixed; left: 0; width: 20%; height: 100%; display: flex; flex-direction: column; justify-content: center; background-color: ${colors.second}; color: ${colors.textMain}; ` const navItem = ` display: flex; align-items: center; margin: 0 1em 0 2em; padding: 0.5em 0; border-bottom: 0.05em solid ${colors.mainHalf}; postion: relative; color: ${colors.textBody}; text-decoration: none; &:before { content: ''; transition: 0.5s; width: 0.5em; height: 0.5em; position: absolute; left: 0.8em; border-radius: 50%; display: block; background-color: ${colors.main}; transform: scale(0); } &:last-child { border-bottom: none; } &:hover { &:before { transform: scale(1); } } ` export default () => ( <StaticQuery query={graphql` { allSitePage { edges { node { id, path } } } } `} render={({ allSitePage: { edges } }) => ( <Sidebar> { edges.map(({ node: { id, path } }) => ( <Link to={path} key={id} css={navItem} >{id}</Link> )) } </Sidebar> )} /> )

Os elementos já existentes são estilizados e é hora de associar o conteúdo ao Contentful , conectar o plug-in de margem e gerar páginas usando a API createPages .
Leia mais sobre como vincular Gatsby e Contentful em um artigo anterior.
Estrutura dos meus dados com Contentful [ { "id": "title", "type": "Symbol" }, { "id": "content", "type": "Text", }, { "id": "link", "type": "Symbol", }, { "id": "orderNumber", "type": "Integer", } ]
Instalação do pacote:
yarn add dotenv gatsby-source-contentful gatsby-transformer-remark
/gatsby-config.js
if (process.env.NODE_ENV === "development") { require("dotenv").config(); } module.exports = { plugins: [ `gatsby-transformer-remark`, { resolve: `gatsby-source-filesystem`, options: { name: `images`, path: `${__dirname}/src/images/`, } }, { resolve: `gatsby-plugin-typography`, options: { pathToConfigModule: `src/utils/typography`, }, }, { resolve: `gatsby-source-contentful`, options: { spaceId: process.env.CONTENTFUL_SPACE_ID, accessToken: process.env.CONTENTFUL_ACCESS_TOKEN, }, }, `gatsby-plugin-sass`, `gatsby-plugin-styled-components`, ], }
Exclua a pasta / src / pages com todos os arquivos internos e crie um novo arquivo para gerenciar os nós no Gatsby:
/gatsby-node.js
const path = require(`path`); /** * , * */ exports.createPages = ({ graphql, actions }) => { /** * * * */ const { createPage } = actions; return graphql(` { allContentfulArticle { edges { node { title link content { childMarkdownRemark { html } } } } } } `).then(({ data: { allContentfulArticle: { edges } } }) => { /** * * createPage() * */ edges.forEach(({ node }) => { createPage({ path: node.link, component: path.resolve(`./src/templates/index.js`), context: { slug: node.link } }); }); }); };
Mais sobre gatsby-node.js
Crie um arquivo de modelo que será a base para as páginas geradas
/src/templates/index.js
import React from "react"; import { graphql } from "gatsby"; import Layout from "../components/layout"; export default ({ data: { allContentfulArticle: { edges: [ { node: { content: { childMarkdownRemark: { html } } } } ] } } }) => { return ( <Layout> <div dangerouslySetInnerHTML={{ __html: html }} /> </Layout> ); }; export const query = graphql` query($slug: String!) { allContentfulArticle(filter: { link: { eq: $slug } }) { edges { node { title link content { childMarkdownRemark { html } } } } } } `;
Por que o componente <StaticQuery />
não é usado aqui? O fato é que ele não suporta variáveis para construir uma solicitação, mas precisamos usar a variável $slug
no contexto da página.
Atualizando a lógica na barra de navegação import React from "react"; import { Link, StaticQuery, graphql } from "gatsby"; import styled from "styled-components"; import { colors } from "../utils/vars"; const Sidebar = styled.section` position: fixed; left: 0; width: 20%; height: 100%; display: flex; flex-direction: column; justify-content: center; background-color: ${colors.second}; color: ${colors.textMain}; `; const navItem = ` display: flex; align-items: center; margin: 0 1em 0 2em; padding: 0.5em 0; border-bottom: 0.05em solid ${colors.main50}; postion: relative; color: ${colors.textBody}; text-decoration: none; &:before { content: ''; transition: 0.5s; width: 0.5em; height: 0.5em; position: absolute; left: 0.8em; border-radius: 50%; display: block; background-color: ${colors.main}; transform: scale(0); } &:last-child { border-bottom: none; } &:hover { &:before { transform: scale(1); } } `; export default () => ( <StaticQuery query={graphql` { allContentfulArticle(sort: { order: ASC, fields: orderNumber }) { edges { node { title link orderNumber } } } } `} render={({ allContentfulArticle: { edges } }) => ( <Sidebar> {edges.map(({ node: { title, link, orderNumber } }) => ( <Link to={link} key={link} css={navItem}> {orderNumber}. {title} </Link> ))} </Sidebar> )} /> );

Otimização SEO
No lado técnico, o site pode ser considerado pronto, então vamos trabalhar com seus metadados. Para fazer isso, precisamos dos seguintes plugins:
yarn add gatsby-plugin-react-helmet react-helmet
O react-helmet gera <head>...</head>
para páginas HTML e, em conjunto com a renderização de Gatsby, é uma ferramenta poderosa e conveniente para trabalhar com SEO.
/src/templates/index.js
import React from "react"; import { graphql } from "gatsby"; import { Helmet } from "react-helmet"; import Layout from "../components/layout"; export default ({ data: { allContentfulArticle: { edges: [ { node: { title, content: { childMarkdownRemark: { html } } } } ] } } }) => { return ( <Layout> <Helmet> <meta charSet="utf-8" /> <title>{title}</title> </Helmet> <div dangerouslySetInnerHTML={{ __html: html }} /> </Layout> ); }; export const query = graphql` query($slug: String!) { allContentfulArticle(filter: { link: { eq: $slug } }) { edges { node { title link content { childMarkdownRemark { html } } } } } } `;
Agora, o title
site sempre corresponderá ao título do artigo, o que afetará significativamente a emissão do site nos resultados da pesquisa especificamente para esse problema. Aqui você pode adicionar facilmente <meta name="description" content=" ">
com uma descrição de cada artigo separadamente, permitindo assim ao usuário entender sobre o que é o artigo na página de pesquisa, em geral, todos os recursos de SEO agora estão disponíveis e gerenciáveis um lugar.

Configuração do PWA
O Gatsby foi projetado para oferecer desempenho de primeira classe imediatamente. Ele cuida dos problemas de separação e minimização de código, além da otimização na forma de pré-carregamento em segundo plano, processamento de imagens etc., para que o site que você cria tenha alto desempenho sem nenhuma configuração manual. Esses recursos de desempenho são uma parte importante do suporte a uma abordagem progressiva de aplicativos da web.
Mas, além de tudo isso, existem três critérios básicos para um site que o define como PWA :
O primeiro ponto não pode ser resolvido pelo Gatsby, já que o domínio , a hospedagem e o protocolo são problemas de implantação e não de desenvolvimento, mas posso recomendar o Netlify , que resolve o problema do https por padrão.
Passamos para os itens restantes, para isso instalaremos dois plugins:
yarn add gatsby-plugin-manifest gatsby-plugin-offline
e configure-os /src/gatsby-config.js
if (process.env.NODE_ENV === "development") { require("dotenv").config(); } module.exports = { plugins: [ { resolve: `gatsby-plugin-manifest`, options: { name: `GatsbyJS translated tutorial`, short_name: `GatsbyJS tutorial`, start_url: `/`, background_color: `#f7f0eb`, theme_color: `#a2466c`, display: `standalone`, icon: `public/favicon.ico`, include_favicon: true } }, `gatsby-plugin-offline`, `gatsby-transformer-remark`, { resolve: `gatsby-source-filesystem`, options: { name: `images`, path: `${__dirname}/src/images/` } }, { resolve: `gatsby-plugin-typography`, options: { pathToConfigModule: `src/utils/typography` } }, { resolve: `gatsby-source-contentful`, options: { spaceId: process.env.CONTENTFUL_SPACE_ID, accessToken: process.env.CONTENTFUL_ACCESS_TOKEN } }, `gatsby-plugin-sass`, `gatsby-plugin-styled-components`, `gatsby-plugin-react-helmet` ] };
Você pode personalizar seu manifesto usando a documentação , bem como personalizar a estratégia de trabalhadores de serviço, substituindo as configurações do plug-in .
Você não notará nenhuma alteração no modo de desenvolvimento, mas o site já atende aos requisitos mais recentes do mundo da web e, quando está hospedado no domínio https: //, não será igual.
Conclusão
Alguns anos atrás, quando eu encontrei problemas ao trazer o aplicativo React para a Internet, apoiá-lo e atualizar o conteúdo, não conseguia imaginar que já existia uma abordagem de pilha JAM no mercado que simplifica todos esses processos e agora não vou me surpreender com isso. simplicidade. Gatsby resolve a maioria dos problemas que afetam o desempenho do site apenas "pronto para uso" e, se você entender um pouco mais sobre os meandros de personalizá-lo para suas necessidades, poderá obter indicadores 100% para todos os itens do Lighthouse , o que afeta significativamente a entrega do site nos mecanismos de pesquisa (por pelo menos no Google).
Repositório com projeto