silverstripe / silverstripe-gatsby
SilverStripe Gatsby base
Installs: 337
Dependents: 0
Suggesters: 0
Security: 0
Stars: 17
Watchers: 14
Forks: 2
Open Issues: 4
Type:silverstripe-vendormodule
pkg:composer/silverstripe/silverstripe-gatsby
Requires
- silverstripe/cms: ^4.4
 - silverstripe/silverstripe-headless: dev-main
 
This package is auto-updated.
Last update: 2025-10-06 18:29:33 UTC
README
This module provides a graphql API that is tailored to provide data to a Gatsby static build. This allows your SilverStripe CMS installation to become a headless data provider for your Gatsby static site generation.
Installation
$ composer require silverstripe/silverstripe-gatsby
Requirements
Your Gatsby project must have the gatsby-source-silverstripe plugin installed.
$ npm install --save gatsby-source-silverstripe
It is also recommended that you use the silverstripe-gatsby-helpers library installed.
$ npm install --save silverstripe-gatsby-helpers
How to use the API
The API has its own endpoint, separate from the SilverStripe admin GraphQL server or any GraphQL you may be using on your frontend.
http://mysite.com/__gatsby/graphql
Querying the data
The query itself is a bit awkward, but in general, the only client accessing this API should be Gatsby itself, and therefore it doesn't have a huge obligation to be developer-friendly.
query Sync($Limit:Int!, $Token:String, $Since:String) {
  sync {
    results(limit: $Limit, offsetToken: $Token, since: $Since) {
      offsetToken # Use this on subsequent requests to chunk results
      nodes {
        id
        parentUUID
        uuid
        created
        lastEdited
        className
        ancestry
        contentFields # All custom fields are flattened into a JSON string
        link # DataObjects are encouraged to provide Link() methods if they appear as pages
        relations {
          type # HAS_ONE, HAS_MANY, etc
          name
          ownerType
          records {
            className
            id
            uuid
          }
        }
      }
    }
  }
}`
Arguments
- limit: Limit the number of records that come back for each query. On a large site, this is critical. Default value: 
1000. - offsetToken: If your previous request provided you with a 
offsetToken, pass it back in here to pick up where the previous result set left off. - since: Essential for incremental/preview builds in Gatsby. Provide a timestamp as a reference to get only records that have changed since then.
 
Controlling what dataobjects are exposed
Obviously, you don't want to expose every single dataobject in the application.
Internals like LoginAttempt and ChangeSet are not remotely useful to a Gatsby
build, where content is the focus.
You can whitelist and blacklist classes, using wildcarding.
SilverStripe\Gatsby\GraphQL\Types\SyncResultTypeCreator: included_dataobjects: myapp: 'MyCompany\MyApp\*' excluded_dataobjects: security: 'SilverStripe\Security\*' versioned: 'SilverStripe\Versioned\*' shortcodes: 'SilverStripe\Assets\Shortcodes\*' siteTreeLink: 'SilverStripe\CMS\Model\SiteTreeLink'
If both a whitelist and blacklist are provided, the blacklist has the final say.
If no whitelist is provided, all dataobjects are in the query by default, until blacklisted.
If no whitelist and no blacklist are provided, don't do that.
Monolithic typing
Due to the complex inheritance patterns in SilverStripe, creating a properly typed
API using unions and interfaces would be a lot of effort and may actually make the developer
experience worse in the end. For now, all types are DataObject, and the Gatsby
source plugin is able to pseudo-type the customFields blob by namespacing each
unserialised field in class-specific subfields.
query {
	allDataObjects {
		# core fields here
		id
		link
		lastEdited
		SilverStripeSiteTree {
			# fields specific to this class are grouped appropriately
			title
			menuTitle
			content
		}
		SilverStripeBlog {
			featuredImage {
				link
			}
			Children {
				link
				# relationships still have to nest their fields
				SilverStripeBlogPost {
					categories {
						title
					}
				}
			}
		}
	}
}
Token-based authentication (for draft content)
Coming soon.