gatsby-source-prismic v3: Previews and Imgix and Types, oh my!
New features that make working with Gatsby and Prismic even better.
Wall-to-Wall Studios recently published a new version of
gatsby-source-prismic
, our plugin for Gatsby, a static site framework, that
pulls in content from Prismic, a content management system. We use Gatsby and
Prismic to create flexible and scalable platforms for our clients’ websites.
We focused this new version on three major features:
- Previews
- Imgix-backed images
- Strongly-typed schemas
The plugin was also rewritten in TypeScript, enabling us to develop and debug new features quicker and with more confidence.
Previews
Sites built with Gatsby ultimately become static sites, i.e. a bunch of HTML, CSS, and JavaScript files. This means a simple web server can serve the site without dealing with more complicated runtimes like Ruby and Node.js. This comes at the cost of not being able quickly preview content changes since Gatsby needs to rebuild all of the files each time content updates are published.
Luckily, Prismic has a preview feature which the Gatsby plugin supports allowing you to dynamically see changes. Editors in Prismic can now click a dedicated “Preview” button to open their site and see their changes.
We designed the plugin’s preview integration to be very flexible, allowing developers to build custom preview functionality specific to their website or application. Our websites, for example, integrate a custom preview interface to provide clients an easy way to toggle between their new and old content.
What it looks like
Integrating previews involves the use of a hook, usePrismicPreview
, and a
function, mergePrismicPreviewData
. The preview hook fetches the preview data
and transforms it to mimic Gatsby’s data structure, while the merge function
combines your static, non-preview data with the updated preview content.
On a dedicated preview page, you would use the hook to fetch the preview.
// usePrismicPreview checks the URL for Prismic's preview data. When it sees // data from Prismic, it fetches the preview, processes the data just like the // Gatsby plugin, and makes it available in `previewData`. // // Once the preview data is loaded, you would save previewData somewhere // globally and redirect to the previewed document's page using `path`. const { isLoading, isPreview, previewData, path } = usePrismicPreview({ repositoryName: 'my-repo', linkResolver: () => (doc) => doc.uid, })
And on your previewed document’s page, you would merge that preview data with the static data.
// On the previewed document's page, merge the static and preview data to // render your previewed page. // // - staticData comes from your Gatsby GraphQL query. // - previewData comes from the usePrismicPreview hook. const data = mergePrismicPreviewData({ staticData, previewData })
How you integrate these two functions is up to you, but we have a detailed walkthrough of a recommended approach here.
Imgix-backed images
Prismic recently upgraded their image APIs to integrate with Imgix. Imgix allows image transformations, including resizing, cropping, and color changes, simply by changing URL parameters. This means we can alter images depending on its context right where it’s used.
With the new version of the plugin, we’ve added support for Imgix-backed images
to be used with
gatsby-image
.
gatsby-image
is a straightforward way to create progressively enhanced images
with placeholders and lazy-loading.
Doing such image transformations prior to the Imgix integration required downloading images and creating thousands of resized versions each time content changed. After moving to URL-based transformations, we’re seeing build times that are up to 4x faster than build-time image resizing.
What it looks like
Using Imgix images from Prismic with gatsby-image
involves querying for the
fluid
or fixed
field on an image and passing that result to gatsby-image
.
// src/pages/home.js import { graphql } from 'gatsby' import Image from 'gatsby-image' const Home = ({ data }) => ( <main> {/* `fluid` contains multiple image sizes and a placeholder. */} <Image fluid={data.imageField.fluid} alt={data.imageField.alt} /> </main> ) export default Home // Query an image for its `fluid` field using a GatsbyPrismicImage fragment. // Don't forget your alt text! export const query = graphql` query { prismicHomePage { data { imageField { fluid(maxWidth: 800) { ...GatsbyPrismicImageFluid } alt } } } } `
Learn more about integrating Imgix with your Gatsby + Prismic sites here.
Strongly-typed schemas
Gatsby works by fetching all possible content from a data source, such as
Prismic, and saves it into memory. It then reads the data and tries to assign
types to each piece. A line of text, for example, would be a String
, while a
list of numbers would be an array of Integer
s.
Sometimes Gatsby does not have enough information to determine the type of content it has been given, so you either get the wrong type back or a nice—but unwanted—error message.
The new version of the plugin resolves this by explicitly telling Gatsby the types of your content. This results in less confusing results and less unexpected error messages. This system also has the nice side-effect of version controlling your Prismic custom types.
Learn more about typing Gatsby’s GraphQL schema here.
Long-term goals
Wall-to-Wall Studios uses this plugin for a number of client websites and plans to continue its use. Since we use it so often, we are able to quickly point out possible improvements and bugs.
We aim to provide a plugin that gives developers their content from Prismic in the best possible format while aligning with Gatsby’s philosophy. Everyone has their own style of programming. As such, we believe API-and-data-first approaches to plugin features that allow you to use Gatsby’s native features is the right decision.
If you’re already using gatsby-source-prismic
, we recommend upgrading to v3 as
soon as you can
(check out the migration guide).
And if you’re not using it, we highly recommend considering the Gatsby and
Prismic combo for its flexibility and ease of development. It has definitely
made us happier.
Be sure to provide any feedback or suggestions on GitHub.