Рубріки: Front-endТеория

Подробно о Gatsby.js: создаем собственный сайт шаг за шагом

Андрій Денисенко

Что такое Gatsby.js

Gatsby.JS — генератор статических сайтов. Он создает статические HTML-страницы с использованием шаблонов, компонентов и данных.

У Gatsby.JS есть преимущества перед статическими веб-сайтами, одностраничными приложениями (SPA) и сайтами с рендерингом на стороне сервера (SSR).

Недостатки статических сайтов

  • Статические сайты сложно обновлять и обслуживать, потому что приходится много раз переписывать один и тот же код для каждой страницы.
  • Для получения каждой страницы статического сайта нужно отправлять отдельный запрос к серверу.
  • Статические сайты обычно не содержат динамических страниц.

Недостатки одностраничных приложений

Недружественны к SEO, потому что в ответ на изначальный запрос возвращается пустая HTML-страница.

Недостатки сайтов с рендерингом на стороне сервера

  • Требуют отправки запроса к серверу для получения каждой страницы.
  • На получение данных сервером и на рендеринг страниц требуется время.

Преимущества генератора Gatsby.js

  • Статические страницы сайтов компилируются во время компоновки, перед развертыванием.
  • Сайты и страницы Gatsby создаются с использованием компонентов React.
  • Статические страницы развертываются в интернете.
  • После изначального запроса поведение сайта напоминает одностраничное приложение.

Сферы применения Gatsby.js

Учитывая простоту поддержки, дружественность к SEO и скорость работы, Gatsby удобно использовать для блогов или маленьких сайтов, быстрых, статических и надежных приложений и веб-страниц.

Пример создания и поддержки блога на Gatsby.js

Базовые знания

Если вы еще не знакомы с веб-разработкой, вам нужно освоить основы HTML, CSS и JavaScript. Также необходимо научиться работать с командной строкой (или терминалом, в зависимости от вашей операционной системы) на базовом уровне.

В свою очередь эта статья познакомит вас с миром Gatsby и React.

Настройка среды разработки

Для работы с Gatsby необходимо установить:

  • Node.js (v18 или новее);
  • Git;
  • интерфейс командной строки Gatsby;
  • редактор кода, например Visual Studio Code.

Node.js

Node.js — это среда, которая может выполнять код JavaScript без веб-браузера. Gatsby создан на основе Node.js. Чтобы начать работу с Gatsby, вам потребуется установить на свой компьютер версию Node.js 18 (или новее).

Npm – это менеджер пакетов, который поставляется в комплекте с Node.js. Вы будете использовать интерфейс командной строки npm, чтобы добавлять пакеты на свой сайт (например, плагины Gatsby) и чтобы запускать задания из командной строки (например, для запуска сайта).

В этой статье приведены инструкции для Ubuntu, Debian и других дистрибутивов, использующих apt.

1. Убедитесь, что ваш дистрибутив Linux готов к установке, запустив команды обновления:

sudo apt update && sudo apt upgrade -y

2. Установите curl, чтобы передавать данные и загружать дополнительные зависимости:

sudo apt-get install curl

3. Затем загрузите новейшую версию nvm, например:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash

4. Чтобы использовать nvm, закройте и снова откройте терминал или запустите команду:

source ~/.bashrc

Убедитесь, что все сработало:

nvm --version

Будет выведена версия nvm.

5. Задайте версию Node.js по умолчанию. После установки nvm конкретная версия node не задается. Необходимо установить нужную вам версию и дать nvm инструкцию использовать ее по умолчанию.

Например:

nvm install 18
nvm use 18

6. Убедитесь, что команды сработали. В результате их выполнения должны быть выведены номера версий.

node --version
npm --version

Теперь можно переходить к следующему шагу.

Git

Есть много материалов по установке Git и созданию репозитория. В данной статье мы дадим краткую инструкцию. Подробнее о Git можно узнать в справочной документации.

1. Установите Git из оболочки с помощью apt-get:

sudo apt-get install git

2. Убедитесь, что Git установлен успешно:

git --version

Будет выведена версия Git.

3. Укажите имя пользователя и пароль Git (замените User Name на свое имя пользователя, а example@domain.com — на свой адрес электронной почты):

git config --global user.name "User Name"
git config --global user.email "example@domain.com"

Интерфейс командной строки Gatsby

Интерфейс командной строки (CLI) Gatsby — это инструмент, позволяющий быстро создавать новые сайты на базе Gatsby и запускать команды для разработки сайтов на Gatsby.

CLI — это пакет npm, и его можно установить с помощью npm.

1. Установите CLI Gatsby на глобальном уровне:

npm install -g gatsby-cli

2. Убедитесь в успешности установки, проверив версию CLI (это должна быть версия 3 или новее), и просмотрите доступные команды:

gatsby --version
gatsby --help

Редактор кода

Нет разницы, с помощью какого редактора кода вы создаете сайт. В документации Gatsby часто приводятся скриншоты из Visual Studio Code (сокращенно — VS Code).

Создание аккаунта

В этой статье мы будем развертывать сайт в облаке Gatsby Cloud. Для этого нужно настроить аккаунт GitHub и аккаунт Gatsby Cloud.

Создание сайта Gatsby

Для создания сайта мы воспользуемся командной строкой Gatsby: gatsby new. Эта команда запускает интерактивный сценарий, который задает вопросы о сайте, который вы хотите создать. После введения всей информации CLI автоматически создает сайт Gatsby в соответствии с вашими ответами.

gatsby new

1. В ответ на вопрос What would you like to call your site? введите название сайта, например My Blog.

2. В ответ на вопрос What would you like to name the folder where your site will be created? оставьте имя папки по умолчанию. Оно будет создано на основе названия сайта.

3. В ответ на следующий вопрос оставьте ответ JavaScript.

4. В ответ на вопрос Will you be using a CMS? выберите No, так же, как и на следующий вопрос Would you like to install a styling system?

5. В ответ на вопрос Would you like to install additional features with other plugins? воспользуйтесь клавишами со стрелками, чтобы выбрать Done и клавишей Enter, чтобы подтвердить выбор.

В результате будет выведена информация о предстоящих действиях:

Thanks! Here's what we'll now do:

🛠 Create a new Gatsby site in the folder my-blog

 

6. В ответ на вопрос Shall we do this? введите Y. После создания сайта будет выведена информация о выполненных действиях:

7. В командной строке перейдите в каталог, созданный для сайта:

cd my-blog

8. Запустите сайт в режиме разработки:

gatsby develop

9. Для открытия сайта перейдите в браузере по адресу http://localhost:8000/

10. Чтобы открыть редактор запросов, перейдите по адресу http://localhost:8000/___graphql

Настройка репозитория GitHub для вашего сайта

Чтобы передать существующий код с вашего компьютера в новый репозиторий GitHub, введите указанные ниже команды в командной строке. Замените плейсхолдер YOUR_GITHUB_USERNAME своим настоящим именем пользователя, а YOUR_GITHUB_REPO_NAME — именем репозитория GitHub (например, my-blog).

git remote add origin https://github.com/YOUR_GITHUB_USERNAME/YOUR_GITHUB_REPO_NAME.git
git branch -M main
git push -u origin main

Облако Gatsby Cloud

Gatsby Cloud — это платформа инфраструктуры, оптимизированная для создания, развертывания и хостинга сайтов Gatsby. Когда вы подключите аккаунт Gatsby Cloud к репозиторию GitHub, Gatsby Cloud создаст ваш сайт, и его смогут посещать другие пользователи.

Чтобы подключить ваш код с GitHub к аккаунту Gatsby Cloud, выполните следующие действия.

1. Откройте панель управления аккаунтом Gatsby Cloud. Нажмите кнопку Add a site («Добавить сайт»).

2. На карточке Import from a Git repository («Импортировать из репозитория Git») щелкните на значке GitHub, чтобы выбрать GitHub в качестве провайдера Git.

3. Если вы впервые подключаете GitHub к облаку Gatsby Cloud, вам потребуется предоставить ему разрешение на доступ к аккаунту GitHub.

4. Откроется новое окно браузера, в котором GitHub запросит разрешение на предоставление доступа для Gatsby Cloud к вашим репозиториям GitHub. Вы можете предоставить доступ либо ко всем репозиториям, либо к отдельному репозиторию, который вы создали (my-blog). Затем нажмите кнопку Install («Установить»).

5. Теперь, когда вы вернетесь в окно Gatsby Cloud, ваш репозиторий окажется в списке. Выберите его, нажав кнопку Import («Импортировать»).

6. После выбора репозитория вы сможете указать некоторые его параметры, но на данный момент оставьте значения по умолчанию и нажмите кнопку Next («Далее»), а в ответ на вопрос, добавить ли интеграции в ваш проект, нажмите кнопку Build Site («Скомпоновать сайт»).

Теперь ваш сайт доступен онлайн.

Каждый раз при отправке изменений (push) в ветку main вашего репозитория GitHub облако Gatsby Cloud будет обнаруживать эти изменения и автоматически запускать компоновку новой версии сайта.

Иерархия страниц и решение вопроса маршрутизации

Чтобы создать страницу в Gatsby, достаточно просто поместить новый файл JSX в папку /src/pages, и он будет скомпилирован в HTML-страницу. Необходимо отметить, что URL-адрес этой страницы будет отвечать фактическому пути с названием.

Мы можем поместить папку /src/pages файлы с публикациями, например так:

Тогда пути к ним будут следующими:

posts/post-01 
posts/post-02

Компоненты, шаблоны и взаимодействие между ними

Gatsby основан на React. Для наполнения страниц в нем используются компоненты React. Рассмотрим их создание на практике.

1. Откройте командную строку и перейдите в папку сайта Gatsby. Запустите команду gatsby develop. Когда сервер запустится, откройте в браузере адрес localhost:8000.

Теперь замените содержимое файла src/pages/index.js:

import * as React from 'react'

const IndexPage = () => {
  return (
    <main>
   <h1>Welcome to my Gatsby blog!</h1>
    </main>
  )
}
export const Head = () => <title>Home Page</title>

export default IndexPage

Сохраните файл, и увидите в браузере такую страницу:

Теперь измените текст между тегами H1:

<h1>Welcome to my cool Gatsby blog!</h1>

Страница в браузере перезагрузится автоматически, и вы увидите обновленный текст.

Добавим страницу о блоге:

import * as React from 'react'

const AboutPage = () => {
  return (
    <main>
   <h1>About</h1>
   <p>Hi there! I built this blog with Gatsby.</p>
    </main>
  )
}

export const Head = () => <title>About</title>

export default AboutPage

Обратите внимание на то, что заголовок задается отдельным компонентом Head.

Компонент Head предоставляется Gatsby Head API. В него можно добавлять различные метаданные для поисковой оптимизации.

export const Head = () => (
  <>
    <title>About</title>
    <meta name="description" content="A Gatsby blog" />
  </>
)

Подробнее о Gatsby Head API вы узнаете из раздела о SEO.

Откройте в браузере адрес localhost:8000/about. Когда сервер разработки завершит перекомпоновку сайта, вы увидите:

SEO: подробнее о Gatsby Head API

Обратите внимание на то, что адреса страниц, создаваемых в каталоге src/pages — названия соответствующих файлов (без расширения js).

Добавление ссылок на страницы

Добавим на созданные страницы ссылки друг на друга.

1. Под объявлением импорта React добавим в оба файла еще одну строку:

import { Link } from 'gatsby'

2. Под заголовком H1 добавим в index.js такую строку:

<Link to="/about">About</Link>

А в about.js — такую:

<Link to="/">Home</Link>

После перекомпиляции под заголовками появятся ссылки.

Создание макета

Если мы начнем создавать дополнительные страницы, то придется повторять в них код заголовка сайта и меню навигации. Чтобы избежать написания лишнего кода, можно создать повторно используемый компонент.

1. Создайте новый файл src/components/layout.js и поместите в него код для создания компонента макета (Layout). В макет будут включены:

  • динамический заголовок (из свойства pageTitle);
  • список навигационных ссылок;
  • контент, передаваемый в свойстве (children).
import * as React from 'react'
import { Link } from 'gatsby'

const Layout = ({ pageTitle, children }) => {
  return (
    <div>
      <nav>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/about">About</Link></li>
        </ul>
      </nav>
      <main>
        <h1>{pageTitle}</h1>
          {children}
      </main>
    </div>
  )
}

export default Layout

Обратите внимание, что свойства макета определяются с использованием немного другой записи:

const Layout = ({ pageTitle, children }) => {
  ...
}

Такой прием называется деструктурированием. В фигурных скобках перечисляются свойства переданного в функцию объекта, что позволяет сократить запись.

Кроме свойств, которые вы можете задавать для своих компонентов, React создает некоторые их свойства автоматически. Одно из таких свойств — children. При рендеринге компонента оно передается автоматически, независимо от того, что находится между тегами компонента.

2. Теперь замените в файлах index.js и about.js строку с импортом ссылки на строку с импортом макета:

import Layout from '../components/layout'

3. В файле index.js замените содержимое между скобками в операторе return на следующее:

<Layout pageTitle="Home Page">
  <p>This is my first Gatsby Blog.</p>
</Layout>

А в файле about.js — на такое:

<Layout pageTitle="About">
  <p>Hi there! I built this blog with Gatsby.</p>
</Layout>

Стилизация программы

После настройки структуры страницы настроим ее внешний вид. Для Gatsby неважно, какой подход вы используете. Можно пользоваться любой системой. Для создания этого блога мы будем использовать модули CSS. Gatsby автоматически настроен на их использование, поэтому дополнительной настройки не требуется.

Модули помещаются в файлы с расширением .module.css, и Gatsby обрабатывает их как модули, а не как чистый CSS.

1. Создайте файл src/components/layout.module.css
Добавьте класс .container:

.container {
  margin: auto;
  max-width: 500px;
  font-family: sans-serif;
}

2. Импортируйте этот класс в свой файл макета после импорта компонента ссылки:

import { container } from './layout.module.css'

3. Затем с помощью свойства className назначьте его для элемента div верхнего уровня:

<div className={container}>

Теперь, когда вы откроете страницы в браузере, увидите, что шрифт изменился, а текст расположился ближе к центру.

4. Добавьте стили и для других компонентов:

.heading {
  color: rebeccapurple;
}
.nav-links {
  display: flex;
  list-style: none;
  padding-left: 0;
}
.nav-link-item {
  padding-right: 2rem;
}
.nav-link-text {
  color: black;
}

5. Затем измените объявление импорта и примените стили к соответствующим элементам. Теперь ваш файл src/components/layout.js будет содержать такой код:

import * as React from 'react'
import { Link } from 'gatsby'
import {
  container,
  heading,
  navLinks,
  navLinkItem,
  navLinkText
} from './layout.module.css'

const Layout = ({ pageTitle, children }) => {
  return (
  <div className={container}>
    <nav>
      <ul className={navLinks}>
        <li className={navLinkItem}>
          <Link to="/" className={navLinkText}>
            Home
          </Link>
        </li>
        <li className={navLinkItem}>
          <Link to="/about" className={navLinkText}>
            About
          </Link>
        </li>
      </ul>
    </nav>
    <main>
      <h1 className={heading}>{pageTitle}</h1>
      {children}
    </main>
  </div>
  )
}

Плагины

С точки зрения Gatsby, плагин — это отдельный пакет npm, который вы устанавливаете, чтобы добавить на сайт дополнительные функции.

В библиотеке плагинов Gatsby есть множество плагинов с разным назначением. Одни представляют собой готовые компоненты, другие добавляют функции аналитики, третьи позволяют получать данные для сайта и так далее.

Мы добавим плагин для вставки изображения на страницу блога.

Чтобы добавить плагин на свой сайт, выполните следующие действия:

  • установите плагин с помощью npm;
  • настройте плагин в файле gatsby-config.js своего сайта;
  • используйте функции плагина на сайте.

Установка gatsby-plugin-image для добавления статического изображения на домашнюю страницу

1. В терминале запустите следующую команду, чтобу установить gatsby-plugin-image вместе с зависимостями:

npm install gatsby-plugin-image gatsby-plugin-sharp gatsby-source-filesystem

2. Добавьте плагины gatsby-plugin-image и gatsby-plugin-sharp в файл gatsby-config.js:

plugins: [
    "gatsby-plugin-image",
    "gatsby-plugin-sharp",
],

После установки и настройки плагинов можно пользоваться компонентом StaticImage. Для него нужно указать следующие свойства:

  • src (строка): URL-адрес изображения, которое нужно загрузить;
  • alt (строка): текст, который будет выводиться для описания изображения. Он выводится, если с загрузкой изображения возникают проблемы.

3. Добавьте объявление импорта плагина в файл index.js:

import { StaticImage } from 'gatsby-plugin-image'

После текста добавьте такой код:

<StaticImage
    alt="Two girls looking at Christmas tree free photo by Comstock"
    src="../images/image.jpg"
/>

В результате главная страница будет выглядеть так:

Работа с данными в Gatsby.js

В предыдущих примерах мы помещали текст непосредственно в компоненты React. Чаще всего удобнее хранить данные в отдельных источниках, например в папках с файлами на языке разметки (markdown) или в системах управления контентом (CMS) и по необходимости извлекать их для использования в компонентах. Благодаря этому можно обновлять контент, не изменяя код.

В Gatsby для этого используется уровень данных. С его помощью можно получать, например, публикации в блогах на WordPress, данные о продуктах на Shopify, а также комбинировать данные из различных источников.

Уровень данных основан на технологии GraphQL — это язык запросов с особым синтаксисом. Он позволяет отправлять запросы к данным прямо из компонентов.

Для передачи данных из источника на уровень данных нужно добавить на сайт плагин источника. Каждый такой плагин предназначен для взаимодействия с определенным источником. Во время компоновки сайта каждый плагин извлекает данные из связанного с ним источника и добавляет их на уровень данных GraphQL.

Чтобы получить данные с уровня данных, в компоненты вставляются запросы GraphQL. При компоновке сайта Gatsby найдет все запросы GraphQL в ваших компонентах, выполнит их и поместит полученные данные в компонент.

Для создания запросов удобно использовать инструмент GraphiQL в веб-браузере. С помощью GraphiQL можно просматривать данные вашего сайта и создавать запросы GraphQL.

Чтобы выполнить запрос GraphQL, нужно сделать следующее:

1. Открыть в браузере адрес localhost:8000/___graphiql.
2. Создать запрос в боковой панели (также в ней доступна справка).
3. Нажать кнопку Execute Query («Выполнить запрос») (кнопка «Воспроизвести» посередине страницы). Ответ в окне результатов будет выглядеть примерно так:

{
  "data": {
    "site": {
      "siteMetadata": {
        "title": "My Blog"
      }
    }
  },
  "extensions": {}
}

Попробуйте изменить значение свойства title в файле gatsby-config.js. После сохранения файла сайт перекомпонуется, после чего можно снова запустить запрос в GraphiQL и просмотреть обновленные данные.

В этой статье мы не будем описывать GraphQL и GraphiQL в деталях. Смотрите подробную информацию в документации.

Вставка данных в компоненты с помощью useStaticQuery

Для извлечения информации с уровня данных и вставки в компонент используется хук (перехватчик) useStaticQuery. Он принимает один параметр: шаблонную строку запроса GraphQL. Этот хук возвращает запрошенные данные, которые можно сохранить в переменной, а затем вставить в компонент.

Ниже показано, как с помощью useStaticQuery получить данные и вставить их в компонент.

  • Импортируйте хук useStaticQuery и тег graphql из пакета gatsby. Тег graphql представляет собой теговый шаблонный литерал. Он указывает Gatsby, что следующая за ним строка является запросом GraphQL, который может быть проанализирован Gatsby и запущен.
  • В компоненте вызовите useStaticQuery с помощью шаблонного тега graphql и вашего запроса из GraphiQL. Сохраните результат в новой переменной, чтобы использовать его в компоненте. Обратите внимание: запрос вставляется в обратные апострофы.
  • Вставьте данные в компонент, используя оператор «точка» (.), чтобы получить нужное поле.

Рассмотрим этот процесс на примере нашего блога.

1. Создайте файл src/components/header.js и вставьте в него такой код:

import * as React from 'react'

import { useStaticQuery, graphql } from 'gatsby'

const Header = () => {
  const data = useStaticQuery(graphql`
    query {
      site {
        siteMetadata {
          title
        }
      }
    }
  `)

  return (
    <header>
      <h1>{data.site.siteMetadata.title}</h1>
    </header>
  )
}

export default Header

2. Теперь импортируйте компонент заголовка в файл макета src/components/layout.js:

import { Link, useStaticQuery, graphql } from 'gatsby'

Под объявлением компонента Layout вставьте код вызова запроса:

const data = useStaticQuery(graphql`
query {
  site {
    siteMetadata {
      title
    }
  }
}
`)

3. Теперь, когда есть переменная с результатами запроса, вы можете передать название сайта в JSX-код компонента Layout. Для получения названия сайта воспользуйтесь оператором JavaScript «точка» (.), который получает значение из data.site.siteMetadata.title. Добавьте его так, чтобы оно выводилось в заголовке вкладки браузера.

Под элементом div с className container вставьте тег заголовка:

<header>{data.site.siteMetadata.title}</header>

4. Задайте стиль заголовка в src/components/layout.module.css:

  • Определите стиль:
.site-title {
    font-size: 3rem;
    color: gray;
    font-weight: 700;
    margin: 3rem 0;
}
  • Импортируйте новый стиль в макет, добавив его в список импортов из ./layout.module.css. Теперь определение импорта будет таким:
import {
    container,
    heading,
    navLinks,
    navLinkItem,
    navLinkText,
    siteTitle,
} from './layout.module.css'
  • Примените стиль к добавленному заголовку:
<header className={siteTitle}>{data.site.siteMetadata.title}</header>

Теперь, если вы измените заголовок сайта в gatsby-config.js, то увидите изменение в браузере.

Обновите тег title страницы About, чтобы выводить заголовки в виде Home Page | My Blog.

SEO: вставка названия страницы в тег title с помощью useStaticQuery

В целях SEO хорошо бы, чтобы в title каждой страницы присутствовало ее название.

1. Создайте файл src/components/seo.js. Вставьте в него приведенный ниже код. Этот компонент принимает один параметр title (дальше мы добавим еще один параметр), применяет useStaticQuery для извлечения заголовка и возвращает тег title с указанной выше структурой.

import * as React from 'react'
import { graphql, useStaticQuery } from 'gatsby'

const Seo = ({ title }) => {
  const data = useStaticQuery(graphql`
    query {
      site {
        siteMetadata {
          title
        }
      }
    }
  `)

  return (
      <title>{title} | {data.site.siteMetadata.title}</title>
  )
}

export default Seo

2. Импортируйте компонент Seo из ../components/seo в файл компонента Index:

import Seo from '../components/seo'

3. Измените строку, в которой используется компонент Head, для использования компонента Seo:

export const Head = () => <Seo title="Home Page" />

4. Сохраните файл, и увидите в заголовке вкладки текст Home Page | My Blog.

5. Подобным образом измените остальные страницы.

Создание страницы блога со списком имен файлов публикаций

Страница Blog будет вести на страницы с публикациями.

1. Создайте страницу блога src/pages/blog.js:

import * as React from 'react'
import Layout from '../components/layout'
import Seo from '../components/seo'

const BlogPage = () => {
  return (
    <Layout pageTitle="My Blog Posts">
      <p>My posts</p>
    </Layout>
  )
}
export const Head = () => <Seo title="Posts" />

export default BlogPage

2. Добавьте ссылку на нее в layout.js (после ссылки на страницу About, перед закрывающим тегом):

<li className={navLinkItem}>
    <Link to="/blog" className={navLinkText}>
        Blog
    </Link>
</li>

3. Создайте несколько публикаций в формате MDX. Каждая публикация будет храниться в отдельном файле в папке blog.

Создайте папку blog на верхнем уровне папки проекта.

Создайте три файла в каталоге blog. Можете назвать их, как захотите, но главное, чтобы они имели расширение .mdx. Пока файлы могут быть пустыми.

4. Чтобы подтянуть их на уровень данных, воспользуйтесь компонентом gatsby-source-filesystem.

5. Настройте gatsby-source-filesystem в файле gatsby-config.js. Для его настройки будет использоваться объект, а не строка, потому что для него нужно указать дополнительные опции. В приведенном ниже примере показано, как добавить файлы с публикациями на уровень данных.

Теперь раздел плагинов будет выглядеть так:

plugins: [
    "gatsby-plugin-image",
    "gatsby-plugin-sharp",
    {
      resolve: "gatsby-source-filesystem",
      options: {
        name: `blog`,
        path: `${__dirname}/blog`,
      }
    },
],

Перезапустите сервер разработки, чтобы задействовать изменения в конфигурации и добавить файлы на уровень данных.

Чтобы получить данные о нескольких файлах одновременно, воспользуйтесь полем allFile. Просмотрите в GraphiQL различные поля, вложенные в поле allFile. Затем создайте запрос с использованием поля allFile, чтобы получить имена всех файлов в папке blog:

query MyQuery {
  allFile {
    nodes {
      name
    }
  }
}

Запустите запрос в GraphiQL. В окне результатов вы увидите примерно такой объект:

{
  "data": {
    "allFile": {
      "nodes": [
        {
          "name": "hello"
        },
        {
          "name": "my-second-post"
        },
        {
          "name": "my-third-post"
        }
      ]
    }
  },
  "extensions": {}
}

6. Чтобы вывести имена публикаций на странице блога, нужно вставить запрос в компонент.

Импортируйте тег graphql из пакета Gatsby в файл blog.js:

import { graphql } from 'gatsby'

Скопируйте запрос, который вы создали с помощью GraphiQL и вставьте его после определения компонента BlogPage:

export const query = graphql`
  query {
    allFile {
      nodes {
        name
      }
    }
  }
`

Добавьте свойство data в определение функции. Измените строку определения, вставив аргумент data:

const BlogPage = ({ data }) => {

Затем замените плейсхолдер (элемент p) списком имен файлов с публикациями. Проведите итерацию по массиву узлов с помощью метода массива JavaScript .map(). Вставьте следующий код между тегами Layout:

<ul>
    {
        data.allFile.nodes.map(node => (
          <li key={node.name}>
            {node.name}
          </li>
        ))
    }
</ul>

Наполнение страниц контентом

На уровне данных информация хранится в специальных объектах, которые называются узлами. Чтобы использовать данные из файлов MDX, используется плагин-преобразователь gatsby-plugin-mdx. Он создает узлы из файлов MDX.

Контент в файле MDX содержится в формате Markdown. Кроме обычной разметки (например, выделения **полужирным** и так далее), такой файл может содержать титул. Титул заключается между тройками дефисов, расположенных в отдельных строках:

---
title: "Hi there!"
date: "2022-12-17"
slug: "hello"
---

Hi there!

I am **Big** Muzzy.

Наполните контентом созданные страницы блога, пользуясь приведенным примером.

Вывод контента публикаций на странице блога

Теперь пора настроить плагин-преобразователь gatsby-plugin-mdx.

1. Запустите в терминале следующую команду, чтобы установить gatsby-plugin-mdx и зависимость (@mdx-js/react).

npm install gatsby-plugin-mdx @mdx-js/react

2. Добавьте gatsby-plugin-mdx в массив плагинов в файле gatsby-config.js, чтобы Gatsby использовал его при компоновке.

3. Замените поле allFile в запросе на странице блога полем allMdx.

4. Измените запрос в GraphiQL. В разделе allMdx откройте список nodes. В списке frontmatter выберите title и date. С помощью аргумента formatString можно изменить формат даты. Например, date(formatString: "MMMM D, YYYY") выведет дату в формате December 19, 2022.

5. Также выберите поле id в списке nodes. Это уникальный идентификатор узлов, добавляемый Gatsby. Ваш запрос примет такой вид:

query MyQuery {
  allMdx {
    nodes {
      frontmatter {
        title
        date
      }
      id
    }
  }
}

6. Запустите запрос. Вы увидите примерно такой результат:

  "data": {
    "allMdx": {
      "nodes": [
        {
          "frontmatter": {
            "title": "Hi there!",
            "date": "December 17, 2022"
          },
          "id": "bf530dd3-c00f-5426-8fc7-c3d25bbdf72d"
        },
        {
          "frontmatter": {
            "title": "My second post",
            "date": "December 18, 2022"
          },
          "id": "c9ef1a76-4aa4-5343-ab8c-efe6031c0ca0"
        },
        {
          "frontmatter": {
            "title": "My third post",
            "date": "December 19, 2022"
          },
          "id": "af610b54-b8da-5428-bae8-fa96c3967932"
        }
      ]
    }
  },
  "extensions": {}
}

7. Отсортируйте записи в порядке убывания даты. Откройте список sort в поле allMdx. В списке sort отметьте аргумент frontmatter и в выпадающем списке выберите DESC.

Запрос примет следующий вид:

query MyQuery {
  allMdx(sort: { frontmatter: { date: DESC } }) {
    nodes {
      frontmatter {
        date(formatString: "MMMM D, YYYY")
        title
      }
      id
    }
  }
}

После его запуска публикации будут перечислены в порядке убывания даты.

8. Добавьте в запрос выдержку из публикации (поле excerpt). В результатах появится выдержка примерно в таком виде:

"excerpt": "Hi there! I am Big Muzzy."

Вывод выдержки на странице блога

1. Замените запрос на странице блога новым запросом:

export const query = graphql`
  query {
    allMdx(sort: { frontmatter: { date: DESC }}) {
      nodes {
        frontmatter {
          date(formatString: "MMMM D, YYYY")
          title
        }
        id
        excerpt
      }
    }
  }
`

2. Обновите JSX страницы блога: замените содержимое тега Layout следующим:

{
    data.allMdx.nodes.map((node) => (
        <article key={node.id}>
            <h2>{node.frontmatter.title}</h2>
            <p>Posted: {node.frontmatter.date}</p>
            <p>{node.excerpt}</p>
        </article>
    ))
}

Динамическая маршрутизация

До сих пор вы создавали по файлу на каждую страницу сайта в каталоге src/pages. Но можно использовать один компонент страницы для создания нескольких страниц.

В титулах файлов MDX указано свойство slug, значения в котором хорошо подходят для обозначения путей.

1. Создайте в каталоге src/pages каталог blog. В нем создайте файл {mdx.frontmatter__slug}.js со следующим кодом:

import * as React from 'react'
import Layout from '../../components/layout'
import Seo from '../../components/seo'

const BlogPost = () => {
  return (
    <Layout pageTitle="Blog Posts">
      <p>Post contents will go here.</p>
    </Layout>
  )
}

export const Head = () => <Seo title="Blog Posts" />

export default BlogPost

Теперь, например, при переходе на страницу http://localhost:8000/blog/hello/ будет выведено содержимое {mdx.frontmatter__slug}.js.

2. Чтобы упорядочить все страницы, относящиеся к блогу, переместите файл blog.js в папку src/pages/blog и переименуйте его в index.js. Исправьте пути:

import Layout from '../../components/layout'
import Seo from '../../components/seo'

3. Откройте адрес localhost:8000/blog/ и проверьте, работает ли страница блога.

Вывод содержимого страниц блога

Gatsby автоматически добавляет некоторые свойства в компонент шаблона каждой страницы. Это id узла уровня данных и поле, используемое для динамической маршрутизации. В нашем случае это frontmatter__slug.

1. Создайте запрос для наполнения страницы с помощью GraphiQL. В этом случае потребуется только один узел, поэтому используем поле mdx, а не allMdx. Найдите поле с использованием id узла. Так будет быстрее, чем с помощью поля frontmatter__slug.

2. Дополните файл {mdx.frontmatter__slug}.js.

  • Импортируйте graphql
import { graphql } from 'gatsby'
  • Вставьте запрос:
export const query = graphql`
  query ($id: String) {
    mdx(id: {eq: $id}) {
      frontmatter {
        title
        date(formatString: "MMMM D, YYYY")
      }
    }
  }
`

3. Передайте компоненту BlogPost аргументы data и children:

const BlogPost = ({ data, children }) => {

4. Замените код в блоке return:

<Layout pageTitle={data.mdx.frontmatter.title}>
    <p>{data.mdx.frontmatter.date}</p>
    {children}
</Layout>

Вставка ссылок на публикации на страницу blog

В файле src/pages/blog/index.js:

  • Добавьте в запрос поле slug под полем title.
  • Добавьте компонент Link в список импорта из пакета gatsby.
import { Link, graphql } from 'gatsby'
  • Измените элемент h2:
<h2>
    <Link to={`/blog/${node.frontmatter.slug}`}>
        {node.frontmatter.title}
    </Link>
</h2>
  • Откройте в браузере адрес localhost:8000/blog/. Заголовки страниц стали ссылками.

SEO: подробнее о Gatsby Head API

Вы уже сделали так, чтобы заголовок страницы присутствовал в теге title. Также можно указать содержимое для meta-тега description (а также других тегов заголовка), чтобы оно выводилось в результатах.

Раньше работа с разделом head велась с помощью react-helmet, но этот плагин устарел и теперь вместо него используется Gatsby Head API.

1. В файле seo.js добавьте description в число аргументов компонента Seo:

Seo: const Seo = ({ title, description }) => {

2. В операторе return добавьте тег описания:

return (
<>
    <title>{title} | {data.site.siteMetadata.title}</title>
    <meta name="description" content={description}/>
</>
)

3. Добавьте в титулы каждого файла MDX строки с определением description.

description: "The first post in my blog"

4. В файле {mdx.frontmatter__slug}.js добавьте description в запрос:

...
frontmatter {
    title
    description
    date(formatString: "MMMM D, YYYY")
}
...

5. Перепишите Head следующим образом:

export const Head = ({data}) => <Seo
  title={data.mdx.frontmatter.title}
  description={data.mdx.frontmatter.description} />

6. Откройте страницу публикации, например http://localhost:8000/blog/my-third-post/
Если проинспектировать ее код, увидим:

Настройка PWA

Чтобы ваш блог отвечал критериям PWA (Progressive Web Application), нужно добавить и настроить манифест (gatsby-plugin-manifest) и сделать блог доступным офлайн (gatsby-plugin-offline). При этом gatsby-plugin-manifest должен указываться раньше, чем gatsby-plugin-offline, чтобы включить его в service worker.

1. Установите плагин gatsby-plugin-manifest:

npm install gatsby-plugin-manifest

2. Добавьте настройки плагина:

{
resolve: `gatsby-plugin-manifest`,
options: {
    name: `My Blog`,
    short_name: `Blog`,
    description: `An example Gatsby blog`,
    start_url: `/`,
    background_color: `#0a68f0`,
    theme_color: `#0a68f0`,
    display: `standalone`,
    icon: `src/images/icon.png`,
    },
}

3. Установите gatsby-plugin-offline:

npm install gatsby-plugin-offline

4. Добавьте его в gatsby-config.js.

5. Скомпонуйте блог и запустите сервер:

npm run build
npm run serve

Теперь можно просмотреть PWA по адресу http://localhost:9000/.

Gatsby.JS или Next.JS?

Gatsby.JS и Next.JS позволяют легко создавать сайты. Что общего между ними и чем они отличаются друг от друга?

Сравнение работы двух фреймворков

Сходства

  • SEO-оптимизация. Gatsby.JS и Next.JS обеспечивают SEO-оптимизацию, в частности, за счет SSR и плагинов. Это ускоряет загрузку страниц.
  • Инкрементальная компоновка. Gatsby.JS и Next.JS используют инкрементальную компоновку, благодаря чему можно изменять контент, не изменяя страницу целиком. За счет этого сокращается время компоновки и страницы создаются быстрее.
  • Повышение производительности и кэширование. И Gatsby.JS, и Next.JS избавляют разработчиков от бремени разделения и оптимизации кода. Они разделяют код в зависимости от маршрутизации.
  • Опыт разработки. Благодаря обширной документации для разработчиков можно быстро настроить и запустить сайт, а также добавлять новые возможности в существующий продукт. Разработчику не приходится учить все с нуля. Требуется лишь базовое знание React.

Различия

  • Рендеринг страниц. Gatsby.JS генерирует HTML-код в процессе сборки, не используя сервер. Next.JS рендерит статический HTML на сервере при каждом новом запросе.
  • Обработка данных. Gatsby.JS конкретно указывает, как извлекать и обрабатывать данные с помощью GraphQL. Next.JS позволяет разработчику управлять данными любым выбранным способом.
  • Расширяемость. Gatsby.JS предоставляет множество инструментов и плагинов для расширения функциональности веб-сайта или приложения. Это, например, встроенные темы, сжатые изображения и компиляторы TypeScript. Темы и другие возможности можно расширять и добавлять в библиотеки. Next.JS не отстает от конкурента и предоставляет обширный набор сторонних инструментов и библиотек. Также в него встроены возможности, которые ранее было сложно добавить в проект React, например, разделение кода, маршрутизация страниц и оптимизация изображений.
  • Масштабируемость. Gatsby.JS не особо подходит для создания крупных приложений, зато Next.JS — идеальный вариант для масштабирования до корпоративного уровня. Gatsby будет достаточно для создания статических веб-страниц или персональных блогов, но если в будущем вы захотите увеличить приложение, оно будет компилироваться медленно, а может и не скомпилироваться вообще. То есть его масштабирование проблематично. Next.JS в противовес Gatsby следует за новейшими тенденциями веб-разработки корпоративного уровня и на данный момент является одним из лучших генераторов для создания крупномасштабных приложений.
  • Безопасность инфраструктуры и данных. Gatsby позволяет разработчикам создавать чрезвычайно быстрые веб-приложения благодаря предварительному рендерингу во время компоновки и использованию CDN. Этот генератор извлекает из источников только запрошенные данные и потому его безопасность находится на довольно высоком уровне. С другой стороны, в NextJS необходимо настраивать серверы с базами данных, обслуживать их и так далее. У него есть частные API и CMS, но поскольку данные находятся на сервере, к ним проще получить доступ.

Когда использовать Gatsby.JS, а когда Next.JS?

Рассмотрим преимущества и недостатки Gatsby и Next.js с точки зрения примеров использования, чтобы узнать, какой генератор когда использовать.

Статические веб-сайты

Gatsby превосходен для создания простых статических веб-сайтов. Такие сайты обычно состоят из нескольких отдельных HTML-страниц, каждая из которых представляет собой физическую веб-страницу. Хороший пример такого сайта — личный блог. Один и тот же контент доступен разным пользователям без обновления в режиме реального времени.

В таких случаях Gatsby будет лучшим вариантом, поскольку контент остается без изменений и на сайте находится прогнозируемое количество веб-страниц. Gatsby предоставляет множество баз данных, API REST, системы CMS и GraphQL. Поскольку Gatsby отделяет веб-сайт от данных, любой ваш сотрудник без навыков программирования может редактировать данные для веб-страниц и компилировать их во время выполнения.

Крупные многопользовательские веб-сайты

Для создания веб-сайта, на котором множество пользователей будет создавать контент и оставлять комментарии, Next.JS будет наилучшим выбором.

Статический веб-сайт с компоновкой во время выполнения абсолютно не подойдет для этого, потому что таким веб-сайтом одновременно пользуется много посетителей. Поэтому Gatsby с компоновкой в режиме реального времени не очень-то подходит для подобных продуктов.

Кроме того, на крупных веб-сайтах вам нужно выводить динамический контент для зарегистрированных пользователей. SSR — одно из множества преимуществ Next JS и лучших стеков веб-разработки, которые подходят для обслуживания множества пользователей на основе аутентификации. Пользователи могут просматривать соответствующий контент сразу же при входе на сайт.

Гибридные веб-приложения

Next.JS превосходит Gatsby, когда нужно выбрать средство для создания гибридных веб-приложений, в которых требуется передавать данные CSR, а также выводить пользовательский интерфейс, используя SSR.

Отдельное веб-приложение состоит из CSR для вошедших пользователей и SSR для новых. Вам необходимо оптимизировать большинство страниц веб-сайтов для SEO. Поскольку контент должен быть динамическим и общедоступным, Next.JS справится с этим лучше, чем Gatsby.

В целом, Next.JS подходит для крупных приложений с большим трафиком, а Gatsby — для маленьких и статических веб-сайтов.

Используйте Next.JS, когда создаете крупномасштабное приложение для управления большим объемом контента и данных, который в будущем возрастет.

Используйте Gatsby, когда работаете над небольшим проектом, для которого особо важны согласованность и безопасность. Он проще с точки зрения настройки, а разработка на нем занимает меньше времени.

Вывод

Ознакомившись с Gatsby, мы можем подытожить наш опыт.

  • Gatsby удобно использовать для быстрого создания небольших статических сайтов и блогов.
  • Этот генератор шаблонов прост в освоении, а работа над проектом не занимает много времени.
  • За счет множества доступных плагинов и готовых тем вы можете развернуть сайт в краткие сроки, а изменять контент можно в реальном времени.
  • Изменения в репозитории сразу же будут переданы в облако Gatsby Cloud.

Дальнейшую информацию вы можете получить в обширной документации по Gatsby, которая также является преимуществом этого генератора шаблонов.

Код блога, который мы создавали в этой статье, лежит в этом репозитории.

Вот вам видео, основанное на официальном тьюториале с сайта Gatsby. Наш блог, кстати, тоже основан на нем.

А вот плейлист на английском языке:

Останні статті

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023