The following example sites are showcasing the possibilities of Gatsby Foreign keys Fields on some simple scenarios.
⚠ Before running any of the following scripts locally ensure the site is using the latest dependencies
# In the root folder of this repo
npm install # install all required packages
npm run build # build the latest version of the local packages
# open the /example/relationships folder
cd examples/relationships
npm run develop # runs `gatsby develop` command
Now you could browse the site on http://localhost:8000 and see GraphiQL explorer on http://localhost:8000/___graphql.
This section explains how the content is modeled. You could follow to the next section "Import the content to your on Kontent.ai project" and explore the models on your own as well as the sample data based on it. Or you could create models manually to familiarize yourself with the Kontent.ai user interface.
Once you create the content models, you could create content items based on these and the site would be capable to handle the content and render it.
Kontent.ai project contains a simple article content base, that could be tagged. There are two content types Article
and Tag
. Kontent.ai project is using two languages en-US
and cs-CZ
to showcase Language variant relationships.
This content type - Article item
- has following structure:
- Title - Text element
- Content - Text element
- Date - Date & Title element
- Slug - URL slug element - auto-generated from title
- Tags - Linked items element - content type limited to
Tag
This content type represents an article, first four elements (Title
, Content
, and Date
) are meant to be used for some sample content that should be displayed on site. The Content
element is set to simple text because of simplicity. Rich text element type possibilities are described in Resolution example. The Slug
element is used to route registration. Tags
element is modeled as Linked items element type because of Linked from relationship example.
- Title - Text element
- Slug - URL slug element - auto-generated from title
This content type represents a simple tag for an article. An article could contain more than one. This tag is modeled because of Linked from relationship example.
Following features are described on simple real-life use cases. All of them is using Gatsby schema customization to connect GraphQL nodes among each other to achieve the queries simplify and to make the site efficient.
Schema extension are being performed right in the web site source code (in gatsby-node.js file) using createSchemaCustomization
method.
If you want to separate this logic, it is possible to create a local Gatsby plugin and define these customization there, as it is showcased in the Kontent.ai Lumen starter, just use createResolvers
method for the customizations. If you want to re-use this code, you could publish the plugin to the npm and then re-use it.
In case you published your schema extension bound to Kontent.ai GraphQL nodes feel free to raise an issue/pull request with plugin description and we are happy to mention it here!
The example is describing possibility of creating relationships among language variants. This relationship could be ensured by extending schema definition.
If you wish to use the Gatsby for bigger multilingual, take a look to the blog post "How to Build Multilingual Sites with Gatsby"
Actual use case is to extend Article
by two fields: fallback_used
and other_languages
.
fallback_used
is aBoolean
field saying it the specified language variant used language fallback or not.other_languages
is a[kontent_item_article]
type, which means it is an array of other GraphQL nodes with typekontent_item_article
, which is the type representingArticle
(you could find type name ininternal.type
field or you could usegetKontentItemNodeTypeName
method from Kontent.ai Gatsby source plugin if you know content type codename).
For the real-life example, there is a listing ot the articles registered on the /articles
route. This page is registered in gatsby-node
file using createPages
API method to register the page using articles.js template. This template is using fallback_used
element to filter out the listing.
So in english (en-US) route /en-US/articles
, you will see all articles:
But in czech version (cs-CZ), there is only one article listed because the only article is translated into Czech language.
The other_languages
field is used in Article detail.
If you open up article detail (article-detail.js template), the other_languages
field is used to load data from the other language variants (URL slug value) to create language selector.
You could see the language selector on the article that has other language variant Humane Typography in the Digital Age:
As mentioned, to createSchemaCustomization
method is used to create a relationships. In this case the method used to link language variants is named linkLanguageVariants
and this is its source code. This method basically using buildObjectType
method to extend the type specified by the method argument. The GraphQL type name is generated from content type codename using getKontentItemNodeTypeName
method from source plugin.
Method responsible for filling the fields with data is a called resolve
. For fallback_used
it is pretty straightforward, but for other_languages
it is more complicated. Take a look to the code comments for possible modifications that changes what data is being retrieved to the field.
Once you extend the schema, it is possible to query the data using GraphQL like that:
{
allKontentItemArticle {
nodes {
fallback_used
preferred_language
system {
language
codename
}
elements {
title {
value
}
}
other_languages {
fallback_used
preferred_language
system {
language
codename
}
elements {
title {
value
}
}
}
}
}
}
Reverse link resolution relationship could be ensured by the schema definition as well.
Implementation is stored in example-used-by-content-item-link.js
file. This implementation is called in gatsby node in this form:
linkUsedByContentItems(api, "article", "tag", "tags", "used_by_articles")
And it basically says: _I have a linked items element linking article
content type with tag
content type. And this element has codename tags
. Make a field used_by_articles
in tag
content type with back references to the articles
.
And then it is easy to load information about tags and articles linked to them source:
{
allKontentItemTag(filter: {preferred_language: {eq: "en-US"}}) {
nodes {
elements {
title {
value
}
}
used_by_articles {
elements {
title {
value
}
slug {
value
}
}
}
}
}
}
This approach is also used in Gatsby Starter Lumen for Kontent.ai if a form of local plugin and then it is used for tags listing to determine number of linked articles.
If you want to import content types with the sample content in your own empty project, you could use following guide:
-
Go to app.kontent.ai and create an empty project
-
Go to "Project Settings", select API keys and copy
Project ID
-
Install Kontent.ai Backup Manager and import data to newly created project from
kontent-backup.zip
file (place appropriate values forapiKey
andprojectId
arguments):npm install -g @kontent-ai/kontent-backup-manager kbm --action=restore --apiKey=<Management API key> --projectId=<Project ID> --zipFilename=kontent-backup
-
Go to your Kontent.ai project and publish all the imported items.
Open the gatsby-config.js
file and set the following properties for @kontent-ai/gatsby-source
plugin:
projectId
from Project settings > API keys > Delivery API > Project IDlanguageCodenames
from Project settings > Localization