{"id":23901715,"url":"https://github.com/bartveneman/gatsby-source-contentful","last_synced_at":"2026-02-28T02:05:03.767Z","repository":{"id":72073938,"uuid":"322324418","full_name":"bartveneman/gatsby-source-contentful","owner":"bartveneman","description":"Monkey patched version of gatsby-source-contentful at v3 to still have some perf benefits","archived":false,"fork":false,"pushed_at":"2020-12-17T14:46:40.000Z","size":117,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-02-23T10:28:13.561Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bartveneman.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-17T14:46:06.000Z","updated_at":"2020-12-17T14:46:43.000Z","dependencies_parsed_at":"2023-02-23T11:15:57.087Z","dependency_job_id":null,"html_url":"https://github.com/bartveneman/gatsby-source-contentful","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bartveneman/gatsby-source-contentful","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bartveneman%2Fgatsby-source-contentful","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bartveneman%2Fgatsby-source-contentful/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bartveneman%2Fgatsby-source-contentful/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bartveneman%2Fgatsby-source-contentful/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bartveneman","download_url":"https://codeload.github.com/bartveneman/gatsby-source-contentful/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bartveneman%2Fgatsby-source-contentful/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29922782,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-27T19:37:42.220Z","status":"online","status_checked_at":"2026-02-28T02:00:07.010Z","response_time":90,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-04T21:52:32.417Z","updated_at":"2026-02-28T02:05:03.758Z","avatar_url":"https://github.com/bartveneman.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gatsby-source-contentful\n\nSource plugin for pulling content types, entries, and assets into Gatsby from\nContentful spaces. It creates links between entry types and asset so they can be\nqueried in Gatsby using GraphQL.\n\nAn example site for using this plugin is at\nhttps://using-contentful.gatsbyjs.org/\n\n## Install\n\n```shell\nnpm install gatsby-source-contentful\n```\n\n## How to use\n\nFirst, you need a way to pass environment variables to the build process, so secrets and other secured data aren't committed to source control. We recommend using [`dotenv`][dotenv] which will then expose environment variables. [Read more about dotenv and using environment variables here][envvars]. Then we can _use_ these environment variables and configure our plugin.\n\n### Using Delivery API\n\n```javascript\n// In your gatsby-config.js\nmodule.exports = {\n  plugins: [\n    {\n      resolve: `gatsby-source-contentful`,\n      options: {\n        spaceId: `your_space_id`,\n        // Learn about environment variables: https://gatsby.dev/env-vars\n        accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,\n      },\n    },\n  ],\n}\n```\n\n### Using Preview API\n\n```javascript\n// In your gatsby-config.js\nmodule.exports = {\n  plugins: [\n    {\n      resolve: `gatsby-source-contentful`,\n      options: {\n        spaceId: `your_space_id`,\n        // Learn about environment variables: https://gatsby.dev/env-vars\n        accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,\n        host: `preview.contentful.com`,\n      },\n    },\n  ],\n}\n```\n\n### Download assets for static distribution\n\nDownloads and caches Contentful Assets to the local filesystem. Useful for reduced data usage in development or projects where you want the assets copied locally with builds for deploying without links to Contentful's CDN.\n\nEnable this feature with the `downloadLocal: true` option.\n\n```javascript\n// In your gatsby-config.js\nmodule.exports = {\n  plugins: [\n    {\n      resolve: `gatsby-source-contentful`,\n      options: {\n        spaceId: `your_space_id`,\n        // Learn about environment variables: https://gatsby.app/env-vars\n        accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,\n        downloadLocal: true,\n      },\n    },\n  ],\n}\n```\n\nQuery a `ContentfulAsset`'s `localFile` field in GraphQL to gain access to the common fields of the `gatsby-source-filesystem` `File` node. This is not a Contentful node, so usage for `gatsby-image` is different:\n\n```graphql\nquery MyQuery {\n  # Example is for a `ContentType` with a `ContentfulAsset` field\n  # You could also query an asset directly via\n  # `allContentfulAsset { edges{ node { } } }`\n  # or `contentfulAsset(contentful_id: { eq: \"contentful_id here\" } ) { }`\n  contentfulMyContentType {\n    myContentfulAssetField {\n      # Direct URL to Contentful CDN for this asset\n      file {\n        url\n      }\n\n      # Query for a fluid image resource on this `ContentfulAsset` node\n      fluid(maxWidth: 500) {\n        ...GatsbyContentfulFluid_withWebp\n      }\n\n      # Query for locally stored file(e.g. An image) - `File` node\n      localFile {\n        # Where the asset is downloaded into cache, don't use this\n        absolutePath\n        # Where the asset is copied to for distribution, equivalent to using ContentfulAsset `file {url}`\n        publicURL\n        # Use `gatsby-image` to create fluid image resource\n        childImageSharp {\n          fluid(maxWidth: 500) {\n            ...GatsbyImageSharpFluid\n          }\n        }\n      }\n    }\n  }\n}\n```\n\nNote: This feature downloads any file from a `ContentfulAsset` node that `gatsby-source-contentful` provides. They are all copied over from `./cache/gatsby-source-filesystem/` to the sites build location `./public/static/`.\n\nFor any troubleshooting related to this feature, first try clearing your `./cache/` directory. `gatsby-source-contentful` will acquire fresh data, and all `ContentfulAsset`s will be downloaded and cached again.\n\n### Offline\n\nIf you don't have internet connection you can add `export GATSBY_CONTENTFUL_OFFLINE=true` to tell the plugin to fallback to the cached data, if there is any.\n\n### Configuration options\n\n**`spaceId`** [string][required]\n\nContentful spaceId\n\n**`accessToken`** [string][required]\n\nContentful delivery api key, when using the Preview API use your Preview API key\n\n**`host`** [string][optional] [default: `'cdn.contentful.com'`]\n\nThe base host for all the API requests, by default it's 'cdn.contentful.com', if you want to use the Preview API set it to `'preview.contentful.com'`. You can use your own host for debugging/testing purposes as long as you respect the same Contentful JSON structure.\n\n**`environment`** [string][optional] [default: 'master']\n\nThe environment to pull the content from, for more info on environments check out this [Guide](https://www.contentful.com/developers/docs/concepts/multiple-environments/).\n\n**`downloadLocal`** [boolean][optional] [default: `false`]\n\nDownloads and caches `ContentfulAsset`'s to the local filesystem. Allows you to query a `ContentfulAsset`'s `localFile` field, which is not linked to Contentful's CDN. Useful for reducing data usage.\n\nYou can pass in any other options available in the [contentful.js SDK](https://github.com/contentful/contentful.js#configuration).\n\n**`localeFilter`** [function][optional] [default: `() =\u003e true`]\n\nPossibility to limit how many locales/nodes are created in GraphQL. This can limit the memory usage by reducing the amount of nodes created. Useful if you have a large space in contentful and only want to get the data from one selected locale.\n\nFor example, to filter locales on only germany `localeFilter: locale =\u003e locale.code === 'de-DE'`\n\nList of locales and their codes can be found in Contentful app -\u003e Settings -\u003e Locales\n\n**`forceFullSync`** [boolean][optional] [default: `false`]\n\nPrevents the use of sync tokens when accessing the Contentful API.\n\n**`proxy`** [object][optional] [default: `undefined`]\n\nAxios proxy configuration. See the [axios request config documentation](https://github.com/mzabriskie/axios#request-config) for further information about the supported values.\n\n**`useNameForId`** [boolean][optional] [default: `true`]\n\nUse the content's `name` when generating the GraphQL schema e.g. a Content Type called `[Component] Navigation bar` will be named `contentfulComponentNavigationBar`.\n\nWhen set to `false`, the content's internal ID will be used instead e.g. a Content Type with the ID `navigationBar` will be called `contentfulNavigationBar`.\n\nUsing the ID is a much more stable property to work with as it will change less often. However, in some scenarios, Content Types' IDs will be auto-generated (e.g. when creating a new Content Type without specifying an ID) which means the name in the GraphQL schema will be something like `contentfulC6XwpTaSiiI2Ak2Ww0oi6qa`. This won't change and will still function perfectly as a valid field name but it is obviously pretty ugly to work with.\n\nIf you are confident your Content Types will have natural-language IDs (e.g. `blogPost`), then you should set this option to `false`. If you are unable to ensure this, then you should leave this option set to `true` (the default).\n\n**`pageLimit`** [number][optional] [default: `100`]\n\nNumber of entries to retrieve from Contentful at a time. Due to some technical limitations, the response payload should not be greater than 7MB when pulling content from Contentful. If you encounter this issue you can set this param to a lower number than 100, e.g `50`.\n\n**`assetDownloadWorkers`** [number][optional] [default: `50`]\n\nNumber of workers to use when downloading contentful assets. Due to technical limitations, opening too many concurrent requests can cause stalled downloads. If you encounter this issue you can set this param to a lower number than 50, e.g 25.\n\n**`richText.resolveFieldLocales`** [boolean][optional] [default: `false`]\n\nIf you want to resolve the locales in fields of assets and entries that are referenced by rich text (e.g., via embedded entries or entry hyperlinks), set this to `true`. Otherwise, fields of referenced assets or entries will be objects keyed by locale.\n\n## Notes on Contentful Content Models\n\nThere are currently some things to keep in mind when building your content models at Contentful.\n\n1. At the moment, fields that do not have at least one populated instance will not be created in the GraphQL schema.\n\n2. When using reference fields, be aware that this source plugin will automatically create the reverse reference. You do not need to create references on both content types.\n\n## How to query for nodes\n\nTwo standard node types are available from Contentful: `Asset` and `ContentType`.\n\n`Asset` nodes will be created in your site's GraphQL schema under `contentfulAsset` and `allContentfulAsset`.\n\n`ContentType` nodes are a little different - their exact name depends on what you called them in your Contentful data models. The nodes will be created in your site's GraphQL schema under `contentful${entryTypeName}` and `allContentful${entryTypeName}`.\n\nIn all cases querying for nodes like `contentfulX` will return a single node, and nodes like `allContentfulX` will return all nodes of that type.\n\n### Query for all nodes\n\nYou might query for **all** of a type of node:\n\n```graphql\n{\n  allContentfulAsset {\n    edges {\n      node {\n        id\n        file {\n          url\n        }\n      }\n    }\n  }\n}\n```\n\nYou might do this in your `gatsby-node.js` using Gatsby's [`createPages`](https://next.gatsbyjs.org/docs/node-apis/#createPages) Node API.\n\n### Query for a single node\n\nTo query for a single `image` asset with the title 'foo' and a width of 1600px:\n\n```javascript\nexport const assetQuery = graphql`\n  {\n    contentfulAsset(filter: { title: { eq: 'foo' } }) {\n      image {\n        resolutions(width: 1600) {\n          width\n          height\n          src\n          srcSet\n        }\n      }\n    }\n  }\n`\n```\n\nTo query for a single `CaseStudy` node with the short text properties `title` and `subtitle`:\n\n```graphql\n  {\n    contentfulCaseStudy(filter: { title: { eq: 'bar' } })  {\n      title\n      subtitle\n    }\n  }\n```\n\n\u003e Note the use of [GraphQL arguments](https://graphql.org/learn/queries/#arguments) on the `contentfulAsset` and `resolutions` fields. See [Gatsby's GraphQL reference docs for more info](https://www.gatsbyjs.org/docs/graphql-reference/).\n\nYou might query for a **single** node inside a component in your `src/components` folder, using [Gatsby's `StaticQuery` component](https://www.gatsbyjs.org/docs/static-query/).\n\n#### A note about LongText fields\n\nOn Contentful, a \"Long text\" field uses Markdown by default. The field is exposed as an object, while the raw Markdown is exposed as a child node.\n\n```graphql\n{\n  contentfulCaseStudy {\n    body {\n      body\n    }\n  }\n}\n```\n\nUnless the text is Markdown-free, you cannot use the returned value directly. In order to handle the Markdown content, you must use a transformer plugin such as [gatsby-transformer-remark](https://www.gatsbyjs.org/packages/gatsby-transformer-remark/). The transformer will create a childMarkdownRemark on the \"Long text\" field and expose the generated html as a child node:\n\n```graphql\n{\n  contentfulCaseStudy {\n    body {\n      childMarkdownRemark {\n        html\n      }\n    }\n  }\n}\n```\n\nYou can then insert the returned HTML inline in your JSX:\n\n```jsx\n\u003cdiv\n  className=\"body\"\n  dangerouslySetInnerHTML={{\n    __html: data.contentfulCaseStudy.body.childMarkdownRemark.html,\n  }}\n/\u003e\n```\n\n#### Duplicated entries\n\nWhen Contentful pulls the data, all localizations will be pulled. Therefore, if you have a localization active, it will duplicate the entries. Narrow the search by filtering the query with `node_locale` filter:\n\n```graphql\n{\n  allContentfulCaseStudy(filter: { node_locale: { eq: \"en-US\" } }) {\n    edges {\n      node {\n        id\n        slug\n        title\n        subtitle\n        body {\n          body\n        }\n      }\n    }\n  }\n}\n```\n\n### Query for Assets in ContentType nodes\n\nMore typically your `Asset` nodes will be mixed inside of your `ContentType` nodes, so you'll query them together. All the same formatting rules for `Asset` and `ContentType` nodes apply.\n\nTo get **all** the `CaseStudy` nodes with ShortText fields `id`, `slug`, `title`, `subtitle`, LongText field `body` and heroImage `Asset` field, we use `allContentful${entryTypeName}` to return all instances of that `ContentType`:\n\n```graphql\n{\n  allContentfulCaseStudy {\n    edges {\n      node {\n        id\n        slug\n        title\n        subtitle\n        body {\n          body\n        }\n        heroImage {\n          fixed(width: 1600) {\n            width\n            height\n            src\n            srcSet\n          }\n        }\n      }\n    }\n  }\n}\n```\n\nWhen querying images you can use the `fixed`, `fluid` or `resize` nodes to get different sizes for the image (for example for using [gatsby-image](https://www.gatsbyjs.org/packages/gatsby-image/)). Their usage is documented at the [gatsby-plugin-sharp](https://www.gatsbyjs.org/packages/gatsby-plugin-sharp/) package. The only difference is that gatsby-source-contentful also allows setting only the `width` parameter for these node types, the height will then automatically be calculated according to the aspect ratio.\n\n## More on Queries with Contentful and Gatsby\n\nIt is strongly recommended that you take a look at how data flows in a real Contentful and Gatsby application to fully understand how the queries, Node.js functions and React components all come together. Check out the example site at\n[using-contentful.gatsbyjs.org](https://using-contentful.gatsbyjs.org/).\n\n## [Contentful Rich Text](https://www.contentful.com/developers/docs/concepts/rich-text/)\n\nRich Text feature is supported in this source plugin, you can use the following query to get the json output:\n\n```graphql\n{\n  allContentfulBlogPost {\n    edges {\n      node {\n        bodyRichText {\n          json\n        }\n      }\n    }\n  }\n}\n```\n\nTo define a way Rich Text document is rendered, you can use `@contentful/rich-text-react-renderer` package:\n\n```jsx\nimport { BLOCKS, MARKS } from \"@contentful/rich-text-types\"\nimport { documentToReactComponents } from \"@contentful/rich-text-react-renderer\"\n\nconst Bold = ({ children }) =\u003e \u003cspan className=\"bold\"\u003e{children}\u003c/span\u003e\nconst Text = ({ children }) =\u003e \u003cp className=\"align-center\"\u003e{children}\u003c/p\u003e\n\nconst options = {\n  renderMark: {\n    [MARKS.BOLD]: text =\u003e \u003cBold\u003e{text}\u003c/Bold\u003e,\n  },\n  renderNode: {\n    [BLOCKS.PARAGRAPH]: (node, children) =\u003e \u003cText\u003e{children}\u003c/Text\u003e,\n  },\n}\n\ndocumentToReactComponents(node.bodyRichText.json, options)\n```\n\nCheck out the examples at [@contentful/rich-text-react-renderer](https://github.com/contentful/rich-text/tree/master/packages/rich-text-react-renderer).\n\n## Sourcing From Multiple Contentful Spaces\n\nTo source from multiple Contentful environments/spaces, add another configuration for `gatsby-source-contentful` in `gatsby-config.js`:\n\n```javascript\n// In your gatsby-config.js\nmodule.exports = {\n  plugins: [\n    {\n      resolve: `gatsby-source-contentful`,\n      options: {\n        spaceId: `your_space_id`,\n        accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,\n      },\n    },\n    {\n      resolve: `gatsby-source-contentful`,\n      options: {\n        spaceId: `your_second_space_id`,\n        accessToken: process.env.SECONDARY_CONTENTFUL_ACCESS_TOKEN,\n      },\n    },\n  ],\n}\n```\n\n[dotenv]: https://github.com/motdotla/dotenv\n[envvars]: https://gatsby.dev/env-vars\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbartveneman%2Fgatsby-source-contentful","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbartveneman%2Fgatsby-source-contentful","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbartveneman%2Fgatsby-source-contentful/lists"}