{"id":13452545,"url":"https://github.com/birkir/gatsby-source-prismic-graphql","last_synced_at":"2025-03-23T19:34:32.709Z","repository":{"id":54914511,"uuid":"164034710","full_name":"birkir/gatsby-source-prismic-graphql","owner":"birkir","description":"Gatsby source plugin for Prismic GraphQL ","archived":true,"fork":false,"pushed_at":"2021-01-21T09:07:31.000Z","size":9915,"stargazers_count":137,"open_issues_count":146,"forks_count":75,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-02-19T12:55:27.097Z","etag":null,"topics":["gatsby","graphql","preview","prismic"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/birkir.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-01-03T23:47:36.000Z","updated_at":"2024-06-20T17:20:46.000Z","dependencies_parsed_at":"2022-08-14T06:31:02.894Z","dependency_job_id":null,"html_url":"https://github.com/birkir/gatsby-source-prismic-graphql","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/birkir%2Fgatsby-source-prismic-graphql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/birkir%2Fgatsby-source-prismic-graphql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/birkir%2Fgatsby-source-prismic-graphql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/birkir%2Fgatsby-source-prismic-graphql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/birkir","download_url":"https://codeload.github.com/birkir/gatsby-source-prismic-graphql/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245159495,"owners_count":20570393,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["gatsby","graphql","preview","prismic"],"created_at":"2024-07-31T07:01:27.126Z","updated_at":"2025-03-23T19:34:31.870Z","avatar_url":"https://github.com/birkir.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# gatsby-source-prismic-graphql\n\nA Gatsby plugin for fetching source data from the [Prismic headless CMS](https://prismic.io) using Prismic's beta [GraphQL API](https://prismic.io/docs/graphql/getting-started/integrate-with-existing-js-project). This plugin provides full support for Prismic's preview feature out of the box.\n\nFor more context, be sure to checkout Prismic's getting started guide: [Using Prismic With Gatsby](https://prismic.io/docs/reactjs/getting-started/prismic-gatsby). This README, however, serves as the most-up-to-date source of information on `gatsby-source-prismic-graphql`'s latest developments and breaking changes.\n\nPlease **be sure your Prismic repository has the GraphQL API enabled**. It is enabled by default on all new Prismic repositories. If you have an older repository or are unable to access `https://[your_repo].prismic.io/graphql`, please reach out to Prismic support to request the GraphQL API.\n\n## Contents\n\n- [Differences From gatsby-source-prismic](#differences-from-gatsby-source-prismic)\n- [Getting Started](#getting-started)\n- [Usage](#usage)\n  - [Automatic Page Generation](#automatic-page-generation)\n  - [Support for Multiple Languages/Locales](#support-for-multiple-languages)\n  - [Page Queries: Fetch Data From Prismic](#page-queries-fetch-data-from-prismic)\n  - [Prismic Previews](#prismic-previews)\n  - [StaticQuery \u0026 useStaticQuery](#staticquery-and-usestaticquery)\n  - [Fragments](#fragments)\n  - [Dynamic Queries \u0026 Fetching](#dynamic-queries-and-fetching)\n  - [Pagination](#pagination)\n  - [Working with gatsby-image](#working-with-gatsby-image)\n  - [Prismic.io A/B Experiments Integration](#prismicio-content-ab-experiments-integration)\n- [How This Plugin Works](#how-this-plugin-works)\n- [Development](#development)\n- [Issues \u0026 Troubleshooting](#issues-and-troubleshooting)\n\n## Differences From `gatsby-source-prismic`\n\n`gatsby-source-prismic-graphql` (this plugin) fetches data using Prismic's beta [GraphQL API](https://prismic.io/docs/graphql/getting-started/integrate-with-existing-js-project) and provides full support for Prismic's Preview feature out of the box. It also provides an easy-to-configure interface for page generation.\n\n[`gatsby-source-prismic`](https://github.com/angeloashmore/gatsby-source-prismic) is a different plugin that fetches data using Prismic's REST and Javascript APIs. Previews must be coded up separately.\n\n## Getting Started\n\n**Install the plugin**\n\n```bash\nnpm install --save gatsby-source-prismic-graphql\n```\n\nor\n\n```bash\nyarn add gatsby-source-prismic-graphql\n```\n\n**Add plugin to `gatsby-config.js` and configure**\n\n```js\n{\n  resolve: 'gatsby-source-prismic-graphql',\n  options: {\n    repositoryName: 'gatsby-source-prismic-test-site', // required\n    defaultLang: 'en-us', // optional, but recommended\n    accessToken: '...', // optional\n    prismicRef: '...', // optional, default: master; useful for A/B experiments\n    path: '/preview', // optional, default: /preview\n    previews: true, // optional, default: true\n    pages: [{ // optional\n      type: 'Article', // TypeName from prismic\n      match: '/article/:uid', // pages will be generated under this pattern\n      previewPath: '/article', // optional path for unpublished documents\n      component: require.resolve('./src/templates/article.js'),\n      sortBy: 'date_ASC', // optional, default: meta_lastPublicationDate_ASC; useful for pagination\n    }],\n    extraPageFields: 'article_type', // optional, extends pages query to pass extra fields\n    sharpKeys: [\n      /image|photo|picture/, // (default)\n      'profilepic',\n    ],\n  }\n}\n```\n\n**Edit your `gatsby-browser.js`**\n\n```js\nconst { registerLinkResolver } = require('gatsby-source-prismic-graphql');\nconst { linkResolver } = require('./src/utils/linkResolver');\n\nregisterLinkResolver(linkResolver);\n```\n\n## Usage\n\n### Automatic Page Generation\n\nYou can generate pages automatically by providing a mapping configuration under the `pages` option in `gatsby-config.js`.\n\nLet's assume we have the following page configuration set:\n\n```js\n{\n  pages: [{\n    type: 'Article',\n    match: '/blogpost/:uid',\n    previewPath: '/blogpost',\n    component: require.resolve('./src/templates/article.js'),\n  }],\n}\n```\n\nIf you have two blog posts with UIDs of `foo` and `bar`, the following URL slugs will be generated:\n\n- `/blogpost/foo`\n- `/blogpost/bar`\n\nIf you create a new unpublished blogpost, `baz` it will be accessible for preview under, assuming you've established a preview session with Prismic:\n\n- `/blogpost?uid=baz`\n\nMore on [Prismic Previews](#prismic-previews) below.\n\n#### Conditionally generating pages\n\nIf the default page generation doesn't cover your use-case, you can provide an optional `filter` option to your individual page configurations.\n\nFor example, if you had a single Prismic _Article_ type and wanted pages with `music` in their UIDs to be generated at a different URL :\n\n```js\n{\n  pages: [{\n    type: 'Article',\n    match: '/musicblog/:uid',\n    filter: data =\u003e data.node._meta.uid.includes('music'),\n    previewPath: '/blogposts',\n    component: require.resolve('./src/templates/article.js'),\n  }, {\n    type: 'Article',\n    match: '/blog/:uid',\n    filter: data =\u003e !data.node._meta.uid.includes('music'),\n    previewPath: '/blogposts',\n    component: require.resolve('./src/templates/article.js'),\n  }],\n}\n```\n\nGiven 3 articles with UIDs of `why-i-like-music`, `why-i-like-sports` and `why-i-like-food`, the following URL slugs will be generated:\n\n- `/musicblog/why-i-like-music`\n- `/blog/why-i-like-sports`\n- `/blog/why-i-like-food`\n\n### Generating pages from page fields\n\nSometimes the meta provided by default doesn't contain enough context to be able to filter pages effectively. By passing `extraPageFields` to the plugin options, we can extend what we can filter on.\n\n```js\n{\n  extraPageFields: 'music_genre',\n  pages: [{\n    type: 'Article',\n    match: '/techno/:uid',\n    filter: data =\u003e data.node.music_genre === 'techno',\n    previewPath: '/blogposts',\n    component: require.resolve('./src/templates/article.js'),\n  }, {\n    type: 'Article',\n    match: '/acoustic/:uid',\n    filter: data =\u003e data.node.music_genre === 'acoustic',\n    previewPath: '/blogposts',\n    component: require.resolve('./src/templates/article.js'),\n  }]\n}\n```\n\nGiven 2 articles with the `music_genre` field set, we'll get the following slugs:\n\n/techno/darude\n/acoustic/mik-parsons\n\n### Support for Multiple Languages\n\nPrismic allows you to create your content in multiple languages. This library supports that too. When setting up your configuration options in `gatsby-config.js`, there are three _optional_ properties you should be aware of: `options.defaultLang`, `options.langs`, and `options.pages[i].langs`. In the following example, all are in use:\n\n```js\n{\n  resolve: 'gatsby-source-prismic-graphql',\n  options: {\n    repositoryName: 'gatsby-source-prismic-test-site',\n    defaultLang: 'en-us',\n    langs: ['en-us', 'es-es', 'is'],\n    path: '/preview',\n    previews: true,\n    pages: [{\n      type: 'Article',\n      match: '/:lang?/:uid',\n      previewPath: '/article',\n      component: require.resolve('./src/templates/article.js'),\n      sortBy: 'date_ASC',\n      langs: ['en-us', 'es-es', 'is'],\n    }, {\n      type: \"Noticias\",\n      match: '/noticias/:uid',\n      previewPath: '/noticias',\n      component: require.resolve('./src/templates/noticias.js'),\n      sortBy: 'date_ASC',\n      langs: ['es-es'],\n    }],\n  }\n}\n```\n\nIn the example above, pages are generated for two document types from Prismic--Articles and Noticias. The latter consists of news stories in Spanish. There are three languages total in use in this blog: US English, Traditional Spanish and Icelandic.\n\nFor Articles, we are instructing the plugin to generate pages for articles of all three languages. But, because there is a question mark (`?`) after the `:lang` portion of the `match` property (`/:lang?/:uid`), we only include the locale tag in the URL slug for languages that are not the `defaultLang` specified above (_i.e._, 'en-us'). So for the following languages, these are the slugs generated:\n\n- US English: `/epic-destinations`\n- Spanish: `/es-es/destinos-increibles`\n- Icelandic: `/is/reykjadalur`\n\nIf we had not specified a `defaultLang`, the slug for US English would have been `/en-us/epic-destinations`. And, in fact, including the `langs: ['en-us', 'es-es', 'is']` declaration for this particular document type (`Articles`) is unnecessary because we already specified that as the default language set right after `defaultLang` in the plugin options.\n\nFor Noticias, however, we only want to generate pages for Spanish documents of that type (`langs` is `[es-es]`). We decide that in this context, no locale tag is needed in the URL slug; \"noticias\" is already enough indication that the contents are in Spanish. So we omit the `:lang` match entirely and specify only `match: '/noticias/:uid'`.\n\nThis is an example of how these three properties can be used together to offer maximum flexibility. To see this in action, check out the [languages example app](https://github.com/birkir/gatsby-source-prismic-graphql/tree/master/examples/languages).\n\n#### (Optional) Short language codes\n\nTo use short language codes (_e.g. `/fr/articles`_) instead of the default (_e.g. `/fr-fr/articles`_), you can set `options.shortenUrlLangs` to `true`.\n\nKeep in mind that if you use this option \u0026 have multiple variants of a language (e.g. _en-us_ and _en-au_) that would be shortened to the same value, you should add UIDs to your URLs to differentiate them.\n\n### Page Queries: Fetch Data From Prismic\n\nIt is very easy to fetch data from Prismic in your pages:\n\n```jsx\nimport React from 'react';\nimport { RichText } from 'prismic-reactjs';\n\nexport const query = graphql`\n  {\n    prismic {\n      page(uid:\"homepage\", lang:\"en-us\") {\n        title\n        description\n      }\n    }\n  }\n`\n\nexport default function Page({ data }) =\u003e \u003c\u003e\n  \u003ch1\u003e{RichText.render(data.prismic.title)}\u003c/h1\u003e\n  \u003ch2\u003e{RichText.render(data.prismic.description)}\u003c/h2\u003e\n\u003c/\u003e\n```\n\n### Prismic Previews\n\nPreviews are enabled by default, however they must be configured in your prismic instance/repository. For instructions on configuring previews in Prismic, refer to Prismic's guide: [How to set up a preview](https://user-guides.prismic.io/preview/how-to-set-up-a-preview/how-to-set-up-a-preview).\n\nWhen testing previews, be sure you are starting from a valid Prismic preview URL/path. The most reliable way to test previews is by using the preview button from your draft in Prismic. If you wish to test the Preview locally, catch the URL that opens immediately after clicking the preview link:\n\n`https://[your-domain.tld]/preview?token=https%3A%2F%[your-prismic-repo].prismic.io%2Fpreviews%2FXRag6xAAACA...ABwjduaa%3FwebsitePreviewId%3DXRA...djaa\u0026documentId=XRBH...jduAa`\n\nThen replace the protocol and domain at the beginning of the URL with your `localhost:PORT` instance, or wherever you're wanting to preview from.\n\nThis URL will be parsed and replaced by the web app and browser with the proper URL as specified in your page configuration.\n\n### StaticQuery and useStaticQuery\n\nYou can use `StaticQuery` as usual, but if you would like to preview them, you must use the `withPreview` function.\n\n[See the example](https://github.com/birkir/gatsby-source-prismic-graphql/tree/master/examples/static-query)\n\n```js\nimport { StaticQuery, graphql } from 'gatsby';\nimport { withPreview } from 'gatsby-source-prismic-graphql';\n\nconst articlesQuery = graphql`\n  query {\n    prismic {\n      ...\n    }\n  }\n`;\n\nexport const Articles = () =\u003e (\n  \u003cStaticQuery\n    query={articlesQuery}\n    render={withPreview(data =\u003e { ... }, articlesQuery)}\n  /\u003e\n);\n```\n\n`useStaticQuery` is not yet supported.\n\n### Fragments\n\nFragments are supported for both page queries and static queries.\n\n[See the example](https://github.com/birkir/gatsby-source-prismic-graphql/tree/master/examples/fragments)\n\n**Within page components**:\n\n```jsx\nimport { graphql } from 'gatsby';\n\nconst fragmentX = graphql` fragment X on Y { ... } `;\n\nexport const query = graphql`\n  query {\n    ...X\n  }\n`;\n\nconst MyPage = (data) =\u003e { ... };\nMyPage.fragments = [fragmentX];\n\nexport default MyPage;\n```\n\n**With StaticQuery**:\n\n```jsx\nimport { StaticQuery, graphql } from 'gatsby';\nimport { withPreview } from 'gatsby-source-prismic-graphql';\n\nconst fragmentX = graphql` fragment X on Y { ... } `;\n\nexport const query = graphql`\n  query {\n    ...X\n  }\n`;\n\nexport default () =\u003e (\n  \u003cStaticQuery\n    query={query}\n    render={withPreview(data =\u003e { ... }, query, [fragmentX])}\n  /\u003e\n);\n\n```\n\n### Dynamic Queries and Fetching\n\nYou can use this plugin to dynamically fetch data for your component using `prismic.load`. Refer to the [pagination example](https://github.com/birkir/gatsby-source-prismic-graphql/tree/master/examples/pagination) to see it in action.\n\n```jsx\nimport React from 'react';\nimport { graphql } from 'gatsby';\n\nexport const query = graphql`\n  query Example($limit: Int) {\n    prismic {\n      allArticles(first: $limit) {\n        edges {\n          node {\n            title\n          }\n        }\n      }\n    }\n  }\n`;\n\nexport default function Example({ data, prismic }) {\n  const handleClick = () =\u003e\n    prismic.load({\n      variables: { limit: 20 },\n      query, // (optional)\n      fragments: [], // (optional)\n    });\n\n  return (\n    // ... data\n    \u003cbutton onClick={handleClick}\u003eload more\u003c/button\u003e\n  );\n}\n```\n\n### Pagination\n\nPagination can be accomplished statically (_i.e._, during initialy page generation) or dynamically (_i.e._, with JS in the browser). Examples of both can be found in the [pagination example](https://github.com/birkir/gatsby-source-prismic-graphql/tree/master/examples/pagination).\n\nPrismic pagination is cursor-based. See Prismic's [Paginate your results](https://prismic.io/docs/graphql/query-the-api/paginate-your-results) article to learn about cursor-based pagination.\n\nBy default, pagination will be sorted by last publication date. If you would like to change that, specify a `sortBy` value in your page configuration in `gatsby-config.js`.\n\n#### Dynamically-Generated Pagination\n\nWhen coupled with `prismic.load`, as demonstrated in the [index page of the pagination example](https://github.com/birkir/gatsby-source-prismic-graphql/tree/master/examples/pagination), other pages can be fetched dynamically using page and cursor calculations.\n\nGraphQL documents from Prismic have a cursor--a base64-encoded string that represents their order, or page number, in the set of all documents queried. We provide two helpers for converting between cursor strings and page numbers:\n\n- `getCursorFromDocumentIndex(index: number)`\n- `getDocumentIndexFromCursor(cursor: string)`\n\n#### Statically-Generated Pagination\n\n##### Basic Pagination\n\nFor basic linking between the pages, metadata for the previous and next pages are provided to you automatically via `pageContext` in the `paginationPreviousMeta` and `paginationNextMeta` properties. These can be used in conjunction with your `linkResolver` to generate links between pages without any additional GraphQL query. For an example of this, take a look at the `\u003cPagination /\u003e` component in the pagination example's [`article.js`](https://github.com/birkir/gatsby-source-prismic-graphql/tree/master/examples/pagination/src/templates/article.js).\n\n##### Enhanced Pagination\n\nIf you would like to gather other information about previous and next pages (say a title or image), simply modify your page query to retrieve those documents. This also is demonstrated in the same [pagination example](https://github.com/birkir/gatsby-source-prismic-graphql/tree/master/examples/pagination/src/templates/article.js) with the `\u003cEnhancedPagination /\u003e` component and the page's GraphQL query.\n\n### Working with gatsby-image\n\nThe latest versions of this plugin support gatsby-image by adding a new property to GraphQL types that contains fields that match the `sharpKeys` array (this defaults to `/image|photo|picture/`) to the `Sharp` suffix.\n\n**Note:** When querying, make sure to also query the source field. For example:\n\n```gql\nquery {\n  prismic {\n    Article(id: \"123\") {\n      title\n      articlePhoto\n      articlePhotoSharp {\n        childImageSharp {\n          fluid(maxWidth: 400, maxHeight: 250) {\n            ...GatsbyImageSharpFluid\n          }\n        }\n      }\n    }\n  }\n}\n```\n\nYou can also get access to specific crop sizes from Prismic by passing the `crop` argument:\n\n```gql\nquery {\n  prismic {\n    Author(id: \"123\") {\n      name\n      profile_picture\n      profile_pictureSharp(crop: \"face\") {\n        childImageSharp {\n          fluid(maxWidth: 500, maxHeight: 500) {\n            ...GatsbyImageSharpFluid\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n**NOTE** Images are not transformed in preview mode, so be sure to fall back to the default image when the sharp image is `null`.\n\n```tsx\nimport Img from 'gatsby-image';\nimport get from 'lodash/get';\n\n// ...\n\nconst sharpImage = get(data, 'prismic.Author.profile_pictureSharp.childImageSharp.fluid');\nreturn sharpImage ? (\n  \u003cImg fluid={sharpImage} /\u003e\n) : (\n  \u003cimg src={get(data, 'prismic.Author.profile_picture.url')} /\u003e\n);\n```\n\nLater, we may add an `Image` component that does this for you and leverages the new Prismic Image API as a fallback for preview modes.\n\n### Prismic.io Content A/B Experiments Integration\n\nYou can use this plugin in combination with Prismic's built-in experiments functionality, and a hosting service like Netlify, to run content A/B tests.\n\nExperiments in Prismic are basically branches of the core content, split into 'refs' similar to git branches. So if you want to get content from a certain experiment variation, you can pass the corresponding ref through to Prismic in your request, and it will return content based on that ref's variation.\n\nA/B experiments are tricky to implement in a static website though; A/B testing needs a way to dynamically serve up the different variations to different website visitors. This is at odds with the idea of a static, non-dynamic website.\n\nFortunately, static hosting providers like Netlify allow you to run A/B tests at a routing level. This makes it possible for us to build multiple versions of our project using different source data, and then within Netlify\nsplit traffic to our different static variations.\n\nTherefore, we can use A/B experiments from Prismic in the following way:\n\n1. Setup an experiment in Prismic.\n\n2. Create a new git branch of your project which will be used to get content. You will need to create a separate git branch for each variation.\n\n3. In that git branch, edit/add the optional 'prismicRef' parameter (documented above). The value of this should be the ref of the variation this git branch is for.\n\n4. Push the newly created branch to your git repo.\n\n5. Now go to your static hosting provider (we'll use Netlify in this example), and setup split testing based on your git branches/Prismic variations.\n\n6. Now your static website will show different experimental variations of the content to different users! At this point the process is manual and non-ideal, but hopefully we'll be able to automate it more in the future.\n\n## How This Plugin Works\n\n1. The plugin creates a new page at `/preview` (by default, you can change this), that will be your preview URL you setup in the Prismic admin interface.\n\n   It will automatically set cookies based on the query parameters and attempt to find the correct page to redirect to with your linkResolver.\n\n2. It uses a different `babel-plugin-remove-graphql-queries` on the client.\n\n   The modified plugin emits your GraphQL queries as a string so they can be read and re-used on the client side by the plugin.\n\n3. Once redirected to a page with the content, everything will load normally.\n\n   In the background, the plugin takes your original Gatsby GraphQL query, extracts the Prismic subquery and uses it to make a GraphQL request to Prismic with a preview reference.\n\n   Once data is received, it will update the `data` prop with merged data from Prismic preview and re-render the component.\n\n## Development\n\n```bash\ngit clone git@github.com:birkir/gatsby-source-prismic-graphql.git\ncd gatsby-source-prismic-graphql\nyarn install\nyarn setup\nyarn start\n\n# select example to work with\ncd examples/default\nyarn start\n```\n\n## Issues and Troubleshooting\n\nPlease raise an issue on GitHub if you have any problems.\n\n### My page GraphQL query does not hot-reload for previews\n\nThis is a Gatsby limitation. You can bypass this limitation by adding the following:\n\n```jsx\nexport const query = graphql` ... `;\nconst MyPage = () =\u003e { ... };\n\nMyPage.query = query; // \u003c-- set the query manually to allow hot-reload.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbirkir%2Fgatsby-source-prismic-graphql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbirkir%2Fgatsby-source-prismic-graphql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbirkir%2Fgatsby-source-prismic-graphql/lists"}