Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

gatsby-source-strapi

gatsby-uc31kMIT5.0.3

Gatsby source plugin for building websites using Strapi as a data source

gatsby, gatsby-plugin, gatsby-source-plugin, strapi

readme

gatsby-source-strapi

Source plugin for pulling documents into Gatsby from a Strapi API.

⚠️ This version of gatsby-source-strapi is only compatible with Strapi v5 and v4. For v3 use this release

This plugin is now maintained publicly by the Gatsby User Collective. Join us in maintaining this piece of software.

<summary>Table of contents</summary>

Installing the plugin

Using yarn

yarn add gatsby-source-strapi gatsby-plugin-image gatsby-plugin-sharp gatsby-source-filesystem gatsby-transformer-remark gatsby-transformer-sharp

Or using NPM

npm install --save gatsby-source-strapi gatsby-plugin-image gatsby-plugin-sharp gatsby-source-filesystem gatsby-transformer-remark gatsby-transformer-sharp

Setting up the plugin

You can enable and configure this plugin in your gatsby-config.js file.

Basic usage

First, you need to configure the STRAPI_API_URL and the STRAPI_TOKEN environment variables. We recommend using dotenv to expose these variables.

Make sure to create a full-access API token in Strapi.

Path: ./.env.development

STRAPI_API_URL=http://127.0.0.1:1337
STRAPI_TOKEN=<my-development-api-token-for-gatsby>

Path: ./gatsby.config.js

require("dotenv").config({
  path: `.env.${process.env.NODE_ENV}`,
});

const strapiConfig = {
  version: 4, // Strapi version 4 or 5, defaults to 5
  apiURL: process.env.STRAPI_API_URL,
  accessToken: process.env.STRAPI_TOKEN,
  collectionTypes: ["article", "company", "author"],
  singleTypes: [],
  maxParallelRequests: 5, // (Optional) Default: Number.POSITIVE_INFINITY
  remoteFileHeaders: {
    /**
     * Customized request headers
     * For http request with a image or other files need authorization
     * For expamle: Fetch a CDN file which has a security config when gatsby building needs
     */
    Referer: "https://your-site-domain/",
    // Authorization: "Bearer eyJhabcdefg_replace_it_with_your_own_token",
  },
};

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-strapi`,
      options: strapiConfig,
    },
  ],
};

Advanced usage

Deep queries populate

const strapiConfig = {
  // ...
  collectionTypes: [
    {
      singularName: "article",
      queryParams: {
        // Populate media and relations
        // Make sure to not specify the fields key so the api always returns the updatedAt
        populate: {
          image: "*",
          images: "*",
          author: {
            populate: {
              avatar: "*",
              company: {
                populate: {
                  image: "*",
                },
              },
            },
          },
        },
      },
    },
  ],
  // ...
};

Draft content

Strapi now supports Draft and publish, which allows you to save your content as a draft and publish it later. By default, this plugin will only fetch the published content.

Draft content should only be pulled when previewing content in the Gatsby preview environment to enable the preview you need to fetch content only when the GATSBY_IS_PREVIEW environment variable is truthy.

Refer to the Gatsby cloud and preview environment setup section to see how to set it up.

Path: ./gatsby.config.js

const strapiConfig = {
  // ...
  collectionTypes: [
    {
      singularName: "article",
      queryParams: {
        publicationState: process.env.GATSBY_IS_PREVIEW === "true" ? "preview" : "live",
        // or the v5 format,
        // we will automatically rewrite publicationState to status:
        // status: process.env.GATSBY_IS_PREVIEW === "true" ? "draft" : "published",
        populate: {
          category: { populate: "*" },
          cover: "*",
          blocks: {
            populate: "*",
          },
        },
      },
    },
  ],
  // ...
};

Then in your GraphQL query you should be able to display published content by using the following query:

{
  allStrapiArticle(filter: { publishedAt: { ne: null } }) {
    nodes {
      id
    }
  }
}
`

Image optimisation

By default all medias are downloaded in the Gatsby file system. To query your asset use the following query:

{
  allStrapiArticle {
    nodes {
      cover {
        localFile {
          childImageSharp {
            gatsbyImageData
          }
        }
      }
    }
  }
}

If you do not want this plugin to download your media (images, videos, and file attachments), you can use the skipFileDownloads configuration option. This may be useful for a site that is using a CDN such as Cloudinary: since the CDN provides image transformations, Gatsby's transformation layer is not needed, and opting out makes the builds faster.

Path: ./gatsby.config.js

const strapiConfig = {
  // ...
  skipFileDownloads: true,
  // ...
};

Rich text field

Rich text fields can now be processed using the gatsby-transformer-remark plugin.

It only works if the content of the rich text field saved in the database is in markdown format. So if you customized the WYSIWYG in your Strapi Administration panel make sure that it is saved in a markdown format.

Files that are added in the richtext field can now also be processed by the gatsby-plugin-image plugin.

To do so, according the restrictons and limitations of the plugin you need to make sure that at least one of your content types entities has a file uploaded in the richtext field.

To query markdown local fields use the following query:

{
  allStrapiArticle {
    nodes {
      # richtext field content
      body {
        # object to access the markdown node
        data {
          # unprocessed data from Strapi
          body
          # processed markdown
          childMarkdownRemark {
            html
            rawMarkdownBody
          }
        }
        # files from the markdown that are processed using the gatsby-image-plugin
        medias {
          # alternative text saved in the markdown
          alternativeText
          # file from the media library
          file {
            # alternative text of the file in the media library
            # it can be different from the one set in your markdown
            alternativeText
          }
          # file processed with gatsby-plugin-image
          localFile {
            childImageSharp {
              gatsbyImageData
            }
          }
          # src set in your markdown field (ex: [alternativeText](src))
          src
          # prefixed url with the Strapi api endpoint of the file
          # when using a provider the src field value is equal to the url field value
          url
        }
      }
    }
  }
}

Components

Strapi components creates unique Gatsby nodes to be able to query a single component in GraphQL using the Gatsby id. To query a specific component use the following query:

{
  strapiComponentSharedRichText(id: { eq: "id" }) {
    id
  }
}

Dynamic zones

To query dynamic zones, write a query using inline GraphQL fragments.

You can use the following query:

{
  allStrapiArticle {
    nodes {
      blocks {
        ... on STRAPI__COMPONENT_SHARED_RICH_TEXT {
          id
          # Since __component is forbidden in gatsby this field is prefixed by strapi_
          strapi_component
        }
        ... on STRAPI__COMPONENT_SHARED_QUOTE {
          id
          strapi_component
        }
        ... on STRAPI__COMPONENT_SHARED_MEDIA {
          id
          strapi_component
        }
        ... on STRAPI__COMPONENT_SHARED_SLIDER {
          id
          strapi_component
        }
      }
    }
  }
}

Internationalization

Content types in Strapi can be localized with the i18n plugin. But by default, gatsby-source-strapi will only fetch data in the default locale of your Strapi app. To specify which locale should be fetched, an i18n object can be provided in the content type's pluginOptions. You can also set the locale to all to get all available localizations of a content type:

const strapiConfig = {
  // ...
  collectionTypes: [
    {
      singularName: "article",
      pluginOptions: {
        i18n: {
          locale: "fr", // Only fetch a specific locale
        },
      },
    },
  ],
  singleTypes: [
    {
      singularName: "global",
      pluginOptions: {
        i18n: {
          locale: "all", // Fetch all localizations
        },
      },
    },
  ],
  // ...
};

Then use the one of the following queries to fetch a localized content type:

{
  # Get content in all available localizations
  allStrapiGlobal {
    nodes {
      locale
    }
  }

  # Get a single type in a specific locale
  strapiGlobal(locale: { eq: "fr" }) {
    locale
  }

  # Get a collection type in a specific locale
  allStrapiArticle(filter: { locale: { eq: "fr" } }) {
    nodes {
      locale
    }
  }
}

Restrictions and limitations

This plugin has several limitations, please be aware of these:

  1. At the moment, fields that do not have at least one populated instance will not be created in the GraphQL schema. This can break your site when field values get removed. You may workaround with an extra content entry with all fields filled out.

  2. When using relational fields, be aware that this source plugin will automatically create the reverse reference for the first level of relation. It is advised to query both articles and categories if you want to link the properly and be able to navigate properly in the GraphQL schema.

  3. In Gatsby, some field names are restricted therefore these fields will be prefixed by strapi_. Here's the list of the restricted field names:

  4. children

  5. fields
  6. internal
  7. parent

changelog

gatsby-source-strapi

5.0.3

Patch Changes

5.0.2

Patch Changes

5.0.1

Patch Changes

5.0.0

Major Changes

  • #498 10ed235 Thanks @laurenskling! - BREAKING CHANGES:

    • This plugin now assumes Strapi 5 by default. If you are on Strapi 4, set version: 4 in your plugin options, see the readme
    • Previously strapi_id was filled with the documentId, now strapi_id will be the regular id.

    documentId is now added as a field. strapi_document_id_or_regular_id contains a mixture of the both. documentId's when they are available, id's for content without a documentId (for example media or components).

    If you use strapi_id in your code assuming it is a Strapi 5 documentId, you have to rewrite that code to use the documentId field. More info why in the PR

4.0.1

Patch Changes

4.0.0

Major Changes

  • #478 5ee9975 Thanks @laurenskling! - Support Strapi v5, while staying compatible with v4.

    There are no breaking changes. I've created a major release because I don't want to bother current applications with possible bugs. Updrading to this code should be a choice.

    I have removed the code for creating the unstable_createNodeManifest. In my believe, this was only for Gatsby Cloud and as Gatsby Cloud only remains in our sweet memories of the glory days, we don't need it anymore. I've also deleted the readme about Gatsby Cloud and content sync, I don't believe any plaform is supporting content sync right now, or ever again.

    I have tried to support both v4 and v5 syntaxes in this release. By setting version on your config to 5, the new REST API syntax will be used. publicationState=preview will automatically be rewritten to status=draft.

    As Strapi v5 is using documentId's over regular id's, I am now using the documentId (where available, f.e. not in components) to create the Gatsby Node id. This should keep updated relations intact when reloading data.

3.3.3

Patch Changes

3.3.2

Patch Changes

  • #461 caf7d4f Thanks @moonmeister! - Updated can-i-use database

  • #461 caf7d4f Thanks @moonmeister! - - Updated testing and runners to latest Node 20 LTS.

    • Updated to latests Yarn v4 and corepack for management of packageManager. Please run corepack enable to use the correct version of yarn.
    • Updated dependencies.
    • Updated prettier and associated formatting.
    • Update TypeScript versions used to latest.
  • #444 b7b48b7 Thanks @renovate! - fix(packages): update non-major dependency versions

  • #453 6a313dc Thanks @renovate! - fix(packages): update non-major dependency versions

3.3.1

Patch Changes

3.3.0

Minor Changes

Patch Changes

3.2.0

Minor Changes

3.1.4

Patch Changes

  • #413 30880d5 Thanks @xSyki! - singleTypes return a 404 when it isn't updated since the latest fetch. Therefor, errors would be silenced. Fix this to report errors that are not 404

  • #397 de090f0 Thanks @konsalex! - add maxParallelRequests config option for users to provide, and refactor to use a single axios instance to all functions

3.1.3

Patch Changes

3.1.2

Patch Changes

3.1.1

Patch Changes

3.1.0

Minor Changes

  • #362 f6c5b3a Thanks @renovate! - fix(packages): update dependency axios to v1 Thanks to @konsalex for some manual testing. Due to the lack of automated tests we cannot guarantee this update won't break anything, please report any issues you may run into.

Patch Changes

  • #399 9a562d8 Thanks @laurenskling! - fix(gatsby-source-strapi) make sure the pagination is not mutated when refetching

3.0.6

Patch Changes

3.0.5

Patch Changes

3.0.4

Patch Changes

3.0.3

Patch Changes

  • #353 56b0306 Thanks @whidy! - feat(gatsby-source-strapi): add a customized headers options that gatsby could request a remote file which may need authorization. Related to #341

3.0.2

Patch Changes

  • #351 3029c4b Thanks @moonmeister! - When plugins are nested inside a Gatsby Theme they are required to have an index.js file in the package root. We recently removed these not knowing this requirement. Files restored and tests added.

3.0.1

Patch Changes

  • #345 65fd3f2 Thanks @laurenskling! - Fix incorectly named variable options_ to options after being introduced ing rewriting the codebase with new linting rules while releasing 3.0.0

3.0.0

Major Changes

  • #331 5eed071 Thanks @laurenskling! - The Strapi company has decided to transfer maintenance for gatsby-source-strapi to the community. The Gatsby User Collective has taken upon itself the task to maintain and release this plugin from now on.

    Changes made:

    Because of these changes, in ownership and in code, we've released this version as a major. It should not contain any breaking changes and upgrading should be possible without any issues.

    Are you dependent on this plugin? Come join us and help grow this plugin as a maintainer.