Use Hygraph with Visual Editor
Visual Editor has first-class support for two-way syncing content between Hygraph and Visual Editor.
Example configuration
Section titled “Example configuration”Visual Editor has a tight integration to support Hygraph as one or more of your content sources. This guide covers how to configure Visual Editor to enable two-way data synchronization with your Hygraph projects.
Here is an example configuration that uses Next.js as the site framework, uses a Page
model to represent pages, and creates a custom sitemap to override the default sitemap behavior:
// stackbit.config.tsimport { defineStackbitConfig, SiteMapEntry, DocumentStringLikeFieldNonLocalized} from '@stackbit/types';import { HygraphContentSource } from "@stackbit/cms-hygraph";
// Use defineStackbitConfig to allow Typescript checksexport default defineStackbitConfig({ stackbitVersion: "~0.6.0", ssgName: "nextjs", nodeVersion: "20",
// useESM: true is required for HygraphContentSource // as it has ESM only dependencies. useESM: true,
contentSources: [ new HygraphContentSource({ // Hygraph project ID. // Can be found in project settings screen in Hygraph Studio. projectId: process.env.HYGRAPH_PROJECT_ID!,
// Hygraph project region. // Can be found in project settings screen in Hygraph Studio. // Example: US-WEST-2 region: process.env.HYGRAPH_REGION!,
// Hygraph project environment. Default: master environment: process.env.HYGRAPH_ENVIRONMENT!,
// Hygraph content API endpoint URL. // Must match the configured region. // Example: // https://{REGION}.cdn.hygraph.com/content/{HASH}/{ENVIRONMENT} contentApi: process.env.HYGRAPH_ENDPOINT!,
// Hygraph management API endpoint URL. // Must match the configured region. // Example: // https://management-{REGION}.hygraph.com/graphql managementApi: process.env.HYGRAPH_MANAGEMENT_API!,
// The management token. managementToken: process.env.HYGRAPH_MANAGEMENT_TOKEN! }) ],
// This marks the Hygraph's "Page" model as a "page" models in the Visual-Editor modelExtensions: [ { name: 'Page', type: 'page' } ],
// The sitemap maps between the "Page" entries and their url paths // allowing easy navigation between site pages in the Visual-Editor. sitemap: ({ documents }): SiteMapEntry[] => { // The "documents" include all the entries from Hygraph. return documents.reduce( (sitemap: SiteMapEntry[], document): SiteMapEntry[] => { // Filter documents that match "Page" model name // This is the model ID in Hygraph. if (!['Page'].includes(document.modelName)) { return sitemap; } const slugField = document.fields.slug as DocumentStringLikeFieldNonLocalized; if (!slugField || !slugField.value) { return sitemap; } sitemap.push({ urlPath: `/${slugField.value.replace(/^\/|\/$/g, '')}`, document: document }); return sitemap; } ); }});
Notice the following:
HygraphContentSource
is being loaded from the@stackbit/cms-hygraph
which must be installed first as a dev-dependency. This package is not needed in your production site.- Hygraph is being configured using local environment variables. Visual Editor will automatically load a
.env
file in the root of your project. - The example assumes a model with an ID of
Page
that is being used to store page data in Hygraph. That content type has a field with nameslug
that determines the URL path at which the page is made available.
Prerequisites
Section titled “Prerequisites”To be able to work with Hygraph, you must first have the following:
-
A Hygraph project with content.
-
The proper API keys that can access your content. For more info check out the options section below.
-
Installed
@stackbit/cms-hygraph
package as a development dependency. (We also recommend@stackbit/types
to help with configuration.)Terminal window npm install -D @stackbit/types @stackbit/cms-hygraph
// stackbit.config.tsimport { defineStackbitConfig } from '@stackbit/types';import { HygraphContentSource } from "@stackbit/cms-hygraph";
export default defineStackbitConfig({ stackbitVersion: "~0.6.0", // ... other config options useESM: true, contentSources: [ new HygraphContentSource({ projectId: "...", region: "...", environment: "...", contentApi: "...", managementApi: "...", managementToken: "...", }) ]});
Options
Section titled “Options”The following are all required options, unless noted:
-
projectId
: The Hygraph project ID, found in the project settings screen in Hygraph Studio. -
region
: The Hygraph project region, found in the project settings screen in Hygraph Studio. -
environment
: The Hygraph project environment. (Default: master) -
contentApi
: The Hygraph content API endpoint URL. Must match the configured region.Example:
https://{REGION}.cdn.hygraph.com/content/{HASH}/{ENVIRONMENT} -
managementApi
: The Hygraph Management API endpoint URL. Must match the configured region.Example:
https://management-{REGION}.hygraph.com/graphql -
managementToken
: The management token. The management token must have the following configuration:-
Content API section:
- Default stage for content delivery: Draft
- Content permissions enabled for all models, all stages, and all locales
-
Management API - The management API must include 21 permissions:
- Read existing environments
- Read existing models
- Read existing components
- Read existing fields
- Read existing enumerations
- Read existing entries
- Read remote sources
- Read stages
- Read locales
- Can see schema view
- Update existing non-published entries
- Update published entries
- Publish non-published entries
- Create new entries
- Delete existing entries
- Create new webhooks
- Read existing webhooks
- Update existing webhooks
- Delete an existing webhook
- Can see Role & Permissions Settings
- Can read content permissions
- (Optional for debugging) Can use the playground
-
-
componentQueryNestingLevel
(Optional): Defines the nesting level in GraphQL queries for cyclic components. This helps reduce query complexity for large content schemas. (Default: 3) -
entriesFilter
: Filters entries fetched byHygraphContentSource
.The
entriesFilter
is applied as the “where” argument in the GraphQL query used to fetch entries. Since each Hygraph model has different “where” properties,entriesFilter
is an object mapping a model’s API ID to its filter value.
The entriesFilter
applies only to the “where” clause, so it cannot be used to filter by locales or stages.
Example:
The following filter retrieves:
- Page entries where
enumField
is “foo” andtitle
contains “homepage.” - Post entries where
author.name
is “john.”
entriesFilter: { Page: '{ enumField: foo, title_contains: "homepage" }', Post: '{ author: { name: "john" } }'}
For more info visit Hygraph Filtering Documentation
-
debugGraphQLQueries
(Optional): Logs GraphQL queries, including complexity details for entry queries.To enable “debug” level logs, run
stackbit dev
with--log-level=debug
flag:Terminal window stackbit dev --log-level=debug -
splitEntryRequestsPerModel
(Optional): Splits GraphQL entry requests by model to reduce query complexity when the content schema is too complex for querying multiple models in a single request.When this flag is set to
false
(the default), a single GraphQL query includes all models, and as pages of entries are fetched, the number of models will decrease:query {Pages(stage: DRAFT, first: 100, skip: 0) {...PageFragment}Posts(stage: DRAFT, first: 100, skip: 0) {...PostFragment}Authors(stage: DRAFT, first: 100, skip: 0) {...AuthorFragment}}When this flag is set to
true
, each GraphQL query will contain a single model, and entries will be fetched serially, one model at a time:Request 1:
query {Pages(stage: DRAFT, first: 100, skip: 0) {...PageFragment}}Request 2:
query {Posts(stage: DRAFT, first: 100, skip: 0) {...PageFragment}}
Store sensitive values
Section titled “Store sensitive values”Sensitive values can be stored in a .env
file, which will then be available when Visual Editor configuration file is loaded.
# .envHYGRAPH_PROJECT_ID=HYGRAPH_REGION=HYGRAPH_ENVIRONMENT=masterHYGRAPH_ENDPOINT=HYGRAPH_MANAGEMENT_API=HYGRAPH_MANAGEMENT_TOKEN=
Local development
Section titled “Local development”Hygraph Content Source uses webhooks to synchronize content. For local development with Visual Editor, the easiest method is to use an ngrok tunnel and pass the tunnel URL when running stackbit dev
.
Install ngrok
Section titled “Install ngrok”If you don’t have ngrok installed, please follow the ngrok quick start guide to install it.
Start ngrok agent
Section titled “Start ngrok agent”With your development server running in one terminal window, open a second terminal and start the ngrok agent on port 8090
:
ngrok http 8090
Once ngrok starts, it will print a publicly-accessible URL in the form of https://xyz.ngrok.app or https://xyz.ngrok.io, which can be used to access localhost:8090. Keep this terminal window open with ngrok running.
Example output:
Session Status online...Forwarding http://xyz.ngrok.app -> http://localhost:8090Forwarding https://xyz.ngrok.app -> http://localhost:8090
Start stackbit dev
Section titled “Start stackbit dev”Open a third terminal window and install the Visual Editor CLI if you haven’t already:
npm i -g @stackbit/cli
Run stackbit dev
with the --csi-webhook-url
argument set to your ngrok public URL, ending with the /_stackbit/onWebhook
path:
stackbit dev --csi-webhook-url=https://<REPLACE>.ngrok.app/_stackbit/onWebhook
Once stackbit dev
starts, open the http://localhost:8090/_stackbit link printed in the terminal to open the Visual Editor.
Content type inference
Section titled “Content type inference”The Hygraph Content Source infers all Hygraph models to be Visual Editor data
models, unless otherwise specified.
Therefore, models that represent website pages must be extended to have type: 'page'
using the modelExtensions
property.
Use multiple projects or environments
Section titled “Use multiple projects or environments”The contentSources
property is an array of content sources that are all pulled together with Visual Editor. You can add another content source by instantiating another class as another item in the array, while using separate environment variables for the options.
// stackbit.config.tsimport { HygraphContentSource } from "@stackbit/cms-hygraph";
export default { contentSources: [ new HygraphContentSource({ projectId: process.env.HYGRAPH_PROJECT_ID_01!, region: process.env.HYGRAPH_REGION_01!, environment: process.env.HYGRAPH_ENVIRONMENT_01!, contentApi: process.env.HYGRAPH_ENDPOINT_01!, managementApi: process.env.HYGRAPH_MANAGEMENT_API_01!, managementToken: process.env.HYGRAPH_MANAGEMENT_TOKEN_01! }), new HygraphContentSource({ projectId: process.env.HYGRAPH_PROJECT_ID_02!, region: process.env.HYGRAPH_REGION_02!, environment: process.env.HYGRAPH_ENVIRONMENT_02!, contentApi: process.env.HYGRAPH_ENDPOINT_02!, managementApi: process.env.HYGRAPH_MANAGEMENT_API_02!, managementToken: process.env.HYGRAPH_MANAGEMENT_TOKEN_02! }) ] // ...};
Did you find this doc useful?
Your feedback helps us improve our docs.