Headless WordPress with Gatsby: How to set up a custom “Gallery” post type for free
Keywords: headless CMS, headless wordpress, gallery, custom post type, Gatsby, ACF, Pods, Custom meta fields, repeatable fields, gatsby-plugin-image, gatsby-source-wordpress, GraphQL
The usecase
I am building a website that contains multiple image galleries. I am using Wordpress as the CMS (in a so called “headless CMS” mode) and build the real site with Gatsby.
This article is about how to customize the Wordpress CMS/Admin interface to include a “Gallery” post type and how to query the resulting data model in Gatsby/Graphql.
This article is NOT about building or designing a gallery component with React/Gatsby.
My requirements/requests/feature requests
The gallery should be both a) user friendly on the Wordpress side and b) its data model should integrate harmoniously with the Gatsby/GraphQL universe. This means:
- it should be free! I don’t want to spend any money on Wordpress plugins (looking at you, ACF Pro)
- the gallery should support any number of images
- the order of images should be defined by the user, ideally by means of a drag’n’drop UI
- it should be compatible with gatsby-source-wordpress (GraphQL based)
- it should be compatible with gatsby-plugin-image
It sounds like a simple use case, but turned out to be harder to realise (if you don’t want to spend money)! I researched 3 solutions, but only the first fulfilled all my requirements: Pods. At the end of the article I share two more alternative solutions.
Solution: Pods! (with a little hack)
The Pods framework is the open source alternative to Advanced Custom Fields (ACF). This tutorial uses Pods version 3.2.1.
First create a pod with name “Gallery” and a field group named “Gallery fields”, then add a field of type “File/Image/Video” named “Images” and set the “upload limit” to “multiple files”
How do I query this in Gatsby?
First you need to enable GraphQL visibility for your pod:
Then query “wpGallery” (the name of your pod prefixed with “wp”) and the field “images” (the name of your custom field):
query MyQuery {
wpGallery(id: {eq: "cG9zdDoyOTA="}) {
id
images {
nodes {
gatsbyImage(width: 900)
}
}
}
}
{
"data": {
"wpGallery": {
"id": "cG9zdDoyOTA=",
"images": {
"nodes": [
{
"gatsbyImage": {
"images": {
"sources": [
{
"srcSet": "/_gatsby/image/358421b5b0035ac93a42cc6d46b7e7ad/2601eded68646ab34949d76d53ad7f2e/wlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.avif?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fwlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.jpg&a=w%3D225%26h%3D150%26fm%3Davif%26q%3D75&cd=e7373efa71b459fa1ff1b97721c3da36 225w,/_gatsby/image/358421b5b0035ac93a42cc6d46b7e7ad/7bb857502b00873ff560c6e47a556b47/wlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.avif?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fwlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.jpg&a=w%3D450%26h%3D300%26fm%3Davif%26q%3D75&cd=e7373efa71b459fa1ff1b97721c3da36 450w,/_gatsby/image/358421b5b0035ac93a42cc6d46b7e7ad/7071a6526579ae261f81b8bc4463365f/wlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.avif?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fwlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.jpg&a=w%3D900%26h%3D600%26fm%3Davif%26q%3D75&cd=e7373efa71b459fa1ff1b97721c3da36 900w,/_gatsby/image/358421b5b0035ac93a42cc6d46b7e7ad/15ac18a8e8615988613cad19537f1c4e/wlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.avif?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fwlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.jpg&a=w%3D1800%26h%3D1200%26fm%3Davif%26q%3D75&cd=e7373efa71b459fa1ff1b97721c3da36 1800w",
"type": "image/avif",
"sizes": "(min-width: 900px) 900px, 100vw"
},
{
"srcSet": "/_gatsby/image/358421b5b0035ac93a42cc6d46b7e7ad/ab11f2182071e384443dffa045bdc85a/wlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.webp?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fwlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.jpg&a=w%3D225%26h%3D150%26fm%3Dwebp%26q%3D75&cd=e7373efa71b459fa1ff1b97721c3da36 225w,/_gatsby/image/358421b5b0035ac93a42cc6d46b7e7ad/bcfaf29f3ee3fb1b3ebbc12a78cfd3a1/wlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.webp?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fwlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.jpg&a=w%3D450%26h%3D300%26fm%3Dwebp%26q%3D75&cd=e7373efa71b459fa1ff1b97721c3da36 450w,/_gatsby/image/358421b5b0035ac93a42cc6d46b7e7ad/e4c8d7aecd9714785ba817d01c221dbc/wlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.webp?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fwlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.jpg&a=w%3D900%26h%3D600%26fm%3Dwebp%26q%3D75&cd=e7373efa71b459fa1ff1b97721c3da36 900w,/_gatsby/image/358421b5b0035ac93a42cc6d46b7e7ad/d3a4d104262dc3a57513c01c59ce88ed/wlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.webp?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fwlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.jpg&a=w%3D1800%26h%3D1200%26fm%3Dwebp%26q%3D75&cd=e7373efa71b459fa1ff1b97721c3da36 1800w",
"type": "image/webp",
"sizes": "(min-width: 900px) 900px, 100vw"
}
],
"fallback": {
"src": "/_gatsby/image/358421b5b0035ac93a42cc6d46b7e7ad/e9e96822177d1cdf77ea1240c2a11d68/wlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.jpg?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fwlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.jpg&a=w%3D225%26h%3D150%26fm%3Djpg%26q%3D75&cd=e7373efa71b459fa1ff1b97721c3da36",
"srcSet": "/_gatsby/image/358421b5b0035ac93a42cc6d46b7e7ad/e9e96822177d1cdf77ea1240c2a11d68/wlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.jpg?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fwlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.jpg&a=w%3D225%26h%3D150%26fm%3Djpg%26q%3D75&cd=e7373efa71b459fa1ff1b97721c3da36 225w,/_gatsby/image/358421b5b0035ac93a42cc6d46b7e7ad/accbf945a4094cd86d6f5636e23417dd/wlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.jpg?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fwlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.jpg&a=w%3D450%26h%3D300%26fm%3Djpg%26q%3D75&cd=e7373efa71b459fa1ff1b97721c3da36 450w,/_gatsby/image/358421b5b0035ac93a42cc6d46b7e7ad/27448af9126a8394bb236d421215d85d/wlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.jpg?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fwlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.jpg&a=w%3D900%26h%3D600%26fm%3Djpg%26q%3D75&cd=e7373efa71b459fa1ff1b97721c3da36 900w,/_gatsby/image/358421b5b0035ac93a42cc6d46b7e7ad/c059c0edbdd574ab1b7bf2f752b4c647/wlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.jpg?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fwlodzimierz-jaworski-2BbwrlmIaX8-unsplash-scaled.jpg&a=w%3D1800%26h%3D1200%26fm%3Djpg%26q%3D75&cd=e7373efa71b459fa1ff1b97721c3da36 1800w",
"sizes": "(min-width: 900px) 900px, 100vw"
}
},
"layout": "constrained",
"width": 900,
"height": 600,
"backgroundColor": "rgb(184,136,88)"
}
},
{
"gatsbyImage": {
"images": {
"sources": [
{
"srcSet": "/_gatsby/image/36980c936cf4dd8450a45772432b0482/3708ce2a4f25ec91a919c6d9555185f8/image-1.avif?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage-1.jpeg&a=w%3D225%26h%3D180%26fm%3Davif%26q%3D75&cd=97ba0befaf041547ee8d103d2944682b 225w,/_gatsby/image/36980c936cf4dd8450a45772432b0482/802098db786cef50e197ef74f50cb348/image-1.avif?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage-1.jpeg&a=w%3D450%26h%3D360%26fm%3Davif%26q%3D75&cd=97ba0befaf041547ee8d103d2944682b 450w,/_gatsby/image/36980c936cf4dd8450a45772432b0482/fb118e5b30f1e15bea9cc774b966092a/image-1.avif?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage-1.jpeg&a=w%3D900%26h%3D720%26fm%3Davif%26q%3D75&cd=97ba0befaf041547ee8d103d2944682b 900w,/_gatsby/image/36980c936cf4dd8450a45772432b0482/d1de0b1a8153f7c6d4e2633c7f5a7a79/image-1.avif?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage-1.jpeg&a=w%3D1800%26h%3D1440%26fm%3Davif%26q%3D75&cd=97ba0befaf041547ee8d103d2944682b 1800w",
"type": "image/avif",
"sizes": "(min-width: 900px) 900px, 100vw"
},
{
"srcSet": "/_gatsby/image/36980c936cf4dd8450a45772432b0482/b8f4e899a486e60196419eb35f37bc5a/image-1.webp?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage-1.jpeg&a=w%3D225%26h%3D180%26fm%3Dwebp%26q%3D75&cd=97ba0befaf041547ee8d103d2944682b 225w,/_gatsby/image/36980c936cf4dd8450a45772432b0482/26f0ddc1a5bd4576bce36b80b070c2ad/image-1.webp?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage-1.jpeg&a=w%3D450%26h%3D360%26fm%3Dwebp%26q%3D75&cd=97ba0befaf041547ee8d103d2944682b 450w,/_gatsby/image/36980c936cf4dd8450a45772432b0482/dc03710d3a93c7667d53754ef3f1253b/image-1.webp?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage-1.jpeg&a=w%3D900%26h%3D720%26fm%3Dwebp%26q%3D75&cd=97ba0befaf041547ee8d103d2944682b 900w,/_gatsby/image/36980c936cf4dd8450a45772432b0482/bec98bd98ea6a7bb83efe73b5ec43d9b/image-1.webp?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage-1.jpeg&a=w%3D1800%26h%3D1440%26fm%3Dwebp%26q%3D75&cd=97ba0befaf041547ee8d103d2944682b 1800w",
"type": "image/webp",
"sizes": "(min-width: 900px) 900px, 100vw"
}
],
"fallback": {
"src": "/_gatsby/image/36980c936cf4dd8450a45772432b0482/6636af1d59a2d8aeba7e72991e51ceaf/image-1.jpg?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage-1.jpeg&a=w%3D225%26h%3D180%26fm%3Djpg%26q%3D75&cd=97ba0befaf041547ee8d103d2944682b",
"srcSet": "/_gatsby/image/36980c936cf4dd8450a45772432b0482/6636af1d59a2d8aeba7e72991e51ceaf/image-1.jpg?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage-1.jpeg&a=w%3D225%26h%3D180%26fm%3Djpg%26q%3D75&cd=97ba0befaf041547ee8d103d2944682b 225w,/_gatsby/image/36980c936cf4dd8450a45772432b0482/8655e58e51785ab73611a2608e69b245/image-1.jpg?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage-1.jpeg&a=w%3D450%26h%3D360%26fm%3Djpg%26q%3D75&cd=97ba0befaf041547ee8d103d2944682b 450w,/_gatsby/image/36980c936cf4dd8450a45772432b0482/d033b7c618abb2f1f62fe01fe409178e/image-1.jpg?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage-1.jpeg&a=w%3D900%26h%3D720%26fm%3Djpg%26q%3D75&cd=97ba0befaf041547ee8d103d2944682b 900w,/_gatsby/image/36980c936cf4dd8450a45772432b0482/582efc2f619e31a1a8a81576ff1f6514/image-1.jpg?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage-1.jpeg&a=w%3D1800%26h%3D1440%26fm%3Djpg%26q%3D75&cd=97ba0befaf041547ee8d103d2944682b 1800w",
"sizes": "(min-width: 900px) 900px, 100vw"
}
},
"layout": "constrained",
"width": 900,
"height": 720,
"backgroundColor": "rgb(88,104,56)"
}
},
{
"gatsbyImage": {
"images": {
"sources": [
{
"srcSet": "/_gatsby/image/4fb3b94908b64bb6f750236008c445e6/2601eded68646ab34949d76d53ad7f2e/image.avif?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage.jpeg&a=w%3D225%26h%3D150%26fm%3Davif%26q%3D75&cd=dc54c0b0da4be912cb958b8bdd61c97a 225w,/_gatsby/image/4fb3b94908b64bb6f750236008c445e6/7bb857502b00873ff560c6e47a556b47/image.avif?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage.jpeg&a=w%3D450%26h%3D300%26fm%3Davif%26q%3D75&cd=dc54c0b0da4be912cb958b8bdd61c97a 450w,/_gatsby/image/4fb3b94908b64bb6f750236008c445e6/7071a6526579ae261f81b8bc4463365f/image.avif?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage.jpeg&a=w%3D900%26h%3D600%26fm%3Davif%26q%3D75&cd=dc54c0b0da4be912cb958b8bdd61c97a 900w",
"type": "image/avif",
"sizes": "(min-width: 900px) 900px, 100vw"
},
{
"srcSet": "/_gatsby/image/4fb3b94908b64bb6f750236008c445e6/ab11f2182071e384443dffa045bdc85a/image.webp?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage.jpeg&a=w%3D225%26h%3D150%26fm%3Dwebp%26q%3D75&cd=dc54c0b0da4be912cb958b8bdd61c97a 225w,/_gatsby/image/4fb3b94908b64bb6f750236008c445e6/bcfaf29f3ee3fb1b3ebbc12a78cfd3a1/image.webp?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage.jpeg&a=w%3D450%26h%3D300%26fm%3Dwebp%26q%3D75&cd=dc54c0b0da4be912cb958b8bdd61c97a 450w,/_gatsby/image/4fb3b94908b64bb6f750236008c445e6/e4c8d7aecd9714785ba817d01c221dbc/image.webp?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage.jpeg&a=w%3D900%26h%3D600%26fm%3Dwebp%26q%3D75&cd=dc54c0b0da4be912cb958b8bdd61c97a 900w",
"type": "image/webp",
"sizes": "(min-width: 900px) 900px, 100vw"
}
],
"fallback": {
"src": "/_gatsby/image/4fb3b94908b64bb6f750236008c445e6/e9e96822177d1cdf77ea1240c2a11d68/image.jpg?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage.jpeg&a=w%3D225%26h%3D150%26fm%3Djpg%26q%3D75&cd=dc54c0b0da4be912cb958b8bdd61c97a",
"srcSet": "/_gatsby/image/4fb3b94908b64bb6f750236008c445e6/e9e96822177d1cdf77ea1240c2a11d68/image.jpg?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage.jpeg&a=w%3D225%26h%3D150%26fm%3Djpg%26q%3D75&cd=dc54c0b0da4be912cb958b8bdd61c97a 225w,/_gatsby/image/4fb3b94908b64bb6f750236008c445e6/accbf945a4094cd86d6f5636e23417dd/image.jpg?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage.jpeg&a=w%3D450%26h%3D300%26fm%3Djpg%26q%3D75&cd=dc54c0b0da4be912cb958b8bdd61c97a 450w,/_gatsby/image/4fb3b94908b64bb6f750236008c445e6/27448af9126a8394bb236d421215d85d/image.jpg?u=http%3A%2F%2Fcms.mywordpresswebsite.de%2Fwp-content%2Fuploads%2F2024%2F05%2Fimage.jpeg&a=w%3D900%26h%3D600%26fm%3Djpg%26q%3D75&cd=dc54c0b0da4be912cb958b8bdd61c97a 900w",
"sizes": "(min-width: 900px) 900px, 100vw"
}
},
"layout": "constrained",
"width": 900,
"height": 600,
"backgroundColor": "rgb(88,168,72)"
}
}
]
}
}
}
}
Now there is one problem: The order in which the images appear in the output of the GraphQL query is not the order in which the images appear in the CMS!
This appears to be a bug in the Pods GraphQL integration.
Workaround: Querying WP RestAPI to get correct image order
I found this workaround:
Wordpress also offers a RestAPI that holds the same data as the GraphQL endpoint. Luckily, in the RestAPI the order of the images is correctly encoded. So we can do an additionally request to this RestAPI just to get the order of the images and then apply this information to the result of the GraphQL query.
First, enable the RestAPI for the pod itself, and then also for the custom fields (!).
Then you can do the following request, e.g. server side in your gatsby-node.js:
const response = await fetch(
"http://cms.mywordpresswebsite.de/wp-json/wp/v2/gallery/293"
)
- /wp-json/wp/v2 is the default endpoint of the Wordpress RestAPI
- /gallery is the name of our pod
- /293 is the id of a specific gallery instance
The JSON output contains an image field which is an array which contains the images in the order in which they were defined in the CMS.
In the JSON output, every image has an ID field that is identical to the databaseId in the GraphQL output. This way both can be matched.
{
"id": 293,
"slug": "gallery-1",
"type": "gallery",
"link": "http://cms.mywordpresswebsite.de/gallery/gallery-1/",
"title": {
"rendered": "Gallery 1"
},
"content": {
"rendered": "",
"protected": false
},
"template": "",
"acf": [],
"images": [
{
"ID": "291",
"guid": "http://cms.mywordpresswebsite.de/wp-content/uploads/2024/05/wlodzimierz-jaworski-2BbwrlmIaX8-unsplash.jpg",
"post_type": "attachment",
"post_mime_type": "image/jpeg",
"pod_item_id": "291"
},
{
"ID": "281",
"guid": "http://cms.mywordpresswebsite.de/wp-content/uploads/2024/05/image-1.jpeg",
"post_type": "attachment",
"pod_item_id": "281"
},
{
"ID": "279",
"guid": "http://cms.mywordpresswebsite.de/wp-content/uploads/2024/05/image.jpeg",
"post_type": "attachment",
"post_mime_type": "image/jpeg",
"pod_item_id": "279"
}
],
}
This is the best solution I could find to build a free gallery admin interface in Wordpress for Gatsby. In the last section I would like to share more attempts to solve this usecase and their pro and cons.
Appendix (Two other solutions)
Solution 2: Advanced Custom Fields (ACF)
When it comes to customizing Wordpress, the “Advanced Custom Fields” (ACF) Wordpress plugin is a big one. ACF has a free version and a paid version (ACF Pro). I am going with the free version. This tutorial uses ACF version 6.2.9.
After creating a custom post type “Gallery” I am looking for any field types that might be a good fit for a gallery, such as “Image” or “Gallery”. Bummer: “Image” does not have a “repeater” option, and “Gallery” is a paid feature of ACF Pro :-(
A workaround could be to set up a fixed number of image fields. This is a bit ugly and does not offer the user much flexibility. But it might be okay in some situations.
How do I query this in Gatsby?
First, make sure that you have enabled the “Show in GraphQL” option in the ACF settings in Wordpress!
Then in the GraphQL query I then query “galleryfields” (or whatever custom name I gave to my fieldgroup, and then query every single image field that I created:
query MyQuery {
allWpGallery {
nodes {
id
title
galleryfields {
image1 {
node {
gatsbyImage(width: 900)
}
}
image2 {
node {
gatsbyImage(width: 900)
}
}
image3 {
node {
gatsbyImage(width: 900)
}
}
}
}
}
}
Tip: It can be useful to use GraphQL fragments to avoid this repetition.
Pros
- Admin interface is constrained to only image fields
- In Gatsby I can access every single image seperately and build whatever components with it
Cons
- predefined number of image fields
- User cant change order easily
Solution 3: A simple Wordpress Page
This solution is pragmatic. The thinking goes: A regular Wordpress page contains a free editor field which can hold almost anything, including images. So it can be used as a gallery: The user inserts the images in the Gutenberg editor as “blocks” in any order. No custom post types or custom meta fields needed.
How do I query this in Gatsby?
In my GraphQL query I then query the field “content” which returns the whole HTML blob which contains the images inline.
Great: The plugin gatsby-source-wordpress converts even the inline images into Gatsby images! (Detailed documentation is available on Github)
Notice how in the response the image source links don’t point to the Wordpress instance anymore, but to the Gatsby site instead (relative path: /_gatsby/file/…).
Pros
- Unlimited, arbitrary number of images
- Good UI for inserting images and changing the image order
Cons
- It’s all one big HTML blob, but I might want to access the images individually to build a completely different markup from them with React
- Too little control over layout, Wordpress includes its own markup and classes
- The standard Wordpress block editor offers users too much freedom