Kurs Profesjonalnego TypeScriptuZobacz teraz
banner
Strona główna / Artykuły / Gatsby - SEO

Gatsby - SEO

Gatsby świetnie się sprawdza w kontekście optymalizacji naszych strony pod silniki wyszukiwania. Sprawdźmy jak w łatwy sposób stworzyć komponent odpowiadający za SEO.

Olaf Sulich

2021-02-01

Gatsby - SEO

Gatsby świetnie się sprawdza w kontekście optymalizacji naszych strony pod silniki wyszukiwania. Sprawdźmy jak w łatwy sposób stworzyć komponent odpowiadający za SEO.

Zacznijmy od zainstalowania paczki react-helmet, będzie ona menadżerem meta tagów znajdujących się w sekcji <head>:

npm i react-helmet

Konfiguracja

Pamiętasz nasz plik konfiguracyjny gatsby-config? To tutaj podawaliśmy wszystkie zainstalowane pluginy. Spełnia on jeszcze jedną, istotną dla nas, funkcję. Możemy w nim zawrzeć obiekt siteMetadata, który będzie odpowiedzialny za podstawowe informacje o naszej stronie. Podajemy tutaj domyśle wartości takie jak tytuł, opis czy zdjęcie.

module.exports = {
  siteMetadata: {
    title: `Louis Edwards`,
    author: `Louis Edwards`,
    description: `Hi! I’m Louis and I am professional photographer since 2001. I’m writing about cameras, design and photographer stuff`,
    siteUrl: process.env.SITE_URL,
    image: `/static/homepage.png`,
    twitterUsername: `louis_edwards_photo`,
  },
...
}

Komponent SEO

Z tak stworzonymi danymi możemy brać się do stworzenia komponentu SEO. Zacznijmy od zdefiniowania zapytania GraphQL:

import React from "react";
import { graphql, useStaticQuery } from "gatsby";
import { Helmet } from "react-helmet";
import { useLocation } from "@reach/router";

const query = graphql`
  query {
    site {
      siteMetadata {
        defaultTitle: title
        defaultDescription: description
        siteUrl
        defaultImage: image
				twitterUsername
      }
    }
  }
`;

Na samej górze importujemy wszystkie niezbędne paczki. Następnie tworzymy zapytanie, tym razem odwołujemy się do site, w którym znajduję się nasz obiekt siteMetadata. Poszczególne dane wybieramy inaczej niż zazwyczaj, korzystamy tutaj z tzw. aliasów. Dzięki temu zamiast odwoływać się do title będziemy korzystać z defaultTitle, przyda nam się to już za chwilę.

Naszym kolejnym krokiem będzie stworzenie komponentu. Korzystamy w nim z kilku niezbędnych propsów. Z zapytania wyciągamy wszelkie potrzebne dane i na ich podstawie tworzymy jeden, główny obiekt konfiguracyjny. To w nim podejmujemy decyzję, które dane w ostateczności będą wykorzystywane w komponencie - te z propsów, czy te z naszego zapytania.

import React from "react";
import { graphql, useStaticQuery } from "gatsby";
import { Helmet } from "react-helmet";
import { useLocation } from "@reach/router";

const query = graphql`
  query {
    site {
      siteMetadata {
        defaultTitle: title
        defaultDescription: description
        siteUrl
        defaultImage: image
      }
    }
  }
`;

const SEO = ({ title, description, image, type }) => {
  const { site } = useStaticQuery(query);
  const { pathname } = useLocation();

  const {
    defaultTitle,
    titleTemplate,
    defaultDescription,
    siteUrl,
    defaultImage,
    twitterUsername,
  } = site.siteMetadata;

  const seo = {
    title: title || defaultTitle,
    description: description || defaultDescription,
    image: `${siteUrl}${image || defaultImage}`,
    url: `${siteUrl}${pathname}`,
  };
};

export default SEO;

Ostatnim krokiem będzie przekazanie przetworzonych danych do odpowiednich meta tagów, które znajdują się w bezpośrednio w komponencie <Helmet>.

import React from "react";
import { graphql, useStaticQuery } from "gatsby";
import { Helmet } from "react-helmet";
import { useLocation } from "@reach/router";

const query = graphql`
  query {
    site {
      siteMetadata {
        defaultTitle: title
        defaultDescription: description
        siteUrl
        defaultImage: image
      }
    }
  }
`;

const SEO = ({ title, description, image, type }) => {
  const { site } = useStaticQuery(query);
  const { pathname } = useLocation();

  const {
    defaultTitle,
    titleTemplate,
    defaultDescription,
    siteUrl,
    defaultImage,
    twitterUsername,
  } = site.siteMetadata;

  const seo = {
    title: title || defaultTitle,
    description: description || defaultDescription,
    image: `${siteUrl}${image || defaultImage}`,
    url: `${siteUrl}${pathname}`,
  };

  return (
    <Helmet title={seo.title}>
      <meta name="description" content={seo.description} />
      <meta name="image" content={seo.image} />
      <meta property="og:url" content={seo.url} />
      <meta property="og:title" content={seo.title} />
      {type === "article" ? (
        <meta property="og:type" content="article" />
      ) : null}
      <meta property="og:description" content={seo.description} />
      <meta property="og:image" content={seo.image} />
      <meta name="twitter:card" content="summary_large_image" />
      <meta name="twitter:creator" content={twitterUsername} />
      <meta name="twitter:title" content={seo.title} />
      <meta name="twitter:description" content={seo.description} />
      <meta name="twitter:image" content={seo.image} />
    </Helmet>
  );
};

export default SEO;

Nasz komponent jest gotowy do wykorzystania, zobaczmy jak się sprawdza na stronie poszczególnego artykułu:

import SEO from "../components/SEO/SEO";

const PostTemplate = ({ data }) => {
  const {
    title,
    category,
    content,
    thumbnail,
    publishedat,
  } = data.datoCmsArticle;

  return (
    <>
      <SEO
        title={title}
        description={content}
        image={thumbnail.src}
        type="article"
      />
	    ...
    </>
  );
}; 

Jak widzisz, do komponentu przekazaliśmy wcześniej pobrane dane oraz nadaliśmy mu typ article, gotowe!

Podsumowanie

Nasz komponent jest gotowy, ale tylko czeka na Twoją rozbudowę! Możesz dodać tutaj więcej meta danych, a nawet skorzystać z JSON-LD.

Cały kod z dzisiejszego artykułu znajdziesz w repozytorium na GitHubie.