Five steps to a Gatsby static website from a TerminusDB Data Product
In this blogpost we will build a static website from a TerminusDB Data Product. We will use our Gatsby starter template (Open Source/MIT) that we just released. The template is intended to be modified and used to build a TerminusDB data product into a static website, and features Tailwind CSS for easy-to-manage utility CSS, rendering markdown documents.
The starter template uses the built-in GraphQL capability of TerminusDB Data Products, and the Gatsby limited but functional GraphQL headless CMS content sourcing functionality. The data product schema in TerminusDB is easy to modify for any use case. For this example, we keep it simple with a very simple blog concept.
The template is fully configured in Typescript to ensure a typed configuration.
We will go through these five steps in this blogpost:
- Clone the Gatsby template repo (and install node.js first)
- Connect GraphQL to your TerminusDB instance (localhost, TerminusCMS or DFRNT)
- Configure the schema and add a first post in DFRNT
- Start the Gatsby development server
- Build a static website that can be uploaded to a webserver
TL;DR; Just link me the repo
The Gatsby repo is hosted as dfrnt-com/gatsby-gql-template on the DFRNT GitHub. Clone it. Setup the .env
with a GraphQL environment variable and URL in the config. Add standard schema templates available in DFRNT to your data product, easiest by signing up and applying them to a new or existing TerminusDB data product.
Clone the Gatsby template repo
You will need Node.js to run Gatsby, and git tooling to clone the Gatsby repository. I think you will need to be at home using the command line and some familiarity with building Javascript, and using git, to make good use of the blogpost.
git clone https://github.com/dfrnt-com/gatsby-gql-template
Connect GraphQL to your TerminusDB instance (localhost, TerminusCMS or DFRNT)
Edit the relevant sections in gatsby-config.ts
, to set the url to the GraphQL endpoint of your TerminusDB data product.
{
// ...
plugins: [
{
resolve: "gatsby-source-graphql",
options: {
typeName: "DFRNT",
fieldName: "dfrnt",
url: "https://dfrnt.com/api/hosted/RustyGearsInc/api/graphql/RustyGearsInc/website",
// Remember to create the .env.development file with the token!
// Or add it to your GitHub secrets if building automatically.
//
// For DFRNT: Configure using the following keys to connect:
// url: "https://dfrnt.com/api/hosted/:instance/api/graphql/:instance/:dataproduct",
//
// For TerminusCMS: Configure using the following keys to connect:
// url: "https://cloud.terminusdb.com/:instance/api/graphql/:instance/:dataproduct",
//
// For Localhost: Configure using the following keys to connect, and set the
// Authorization header below to Basic instead of Token.
// Put a base64 encoded "user:pass" string in `.env.development` for TERMINUSDB_TOKEN
// url: "http://localhost/api/graphql/:instance/:dataproduct",
headers: {
Authorization: `Token ${process.env.TERMINUSDB_TOKEN}`,
},
fetchOptions: {},
},
},
// ...
],
// ...
}
Copy the .env.development.template
into .env.development
and customize with your TerminusCMS (freemium) or a DFRNT API token (by signing up for the free trial). You can still configure the schema using the free DFRNT offering, with data products hosted for free at TerminusCMS, and the GraphQL capabilities offered from there.
Create the .env.development
for the gatsby local development environment, and a .env.production
for the running the production build that produces a static version of the website.
You can also connect to GraphQL running in TerminusDB on a localhost (127.0.0.1) instance, using Basic auth. In gatsby-config.ts
, replace Token
in the Authorization with Basic
and add your user:pass
as a base64 string without newline (it's dXNlcjpwYXNz
for user:pass). Please put an issue if you don't get it to work so we can update the instructions.
Configure the schema and add a first post in DFRNT
Now it's time to create the schema, and you should create a schema that looks like this:
The OpenGraphType
of OpenGraphMetadata
is an enum of website
, article
, book
, and profile
.
Add them manually based on the type composition graph above, or import them using the DFRNT Schema Template section (as they have interdependencies, they need to be added in order):
And finally, add a simple blogpost with some Markdown, either directly into TerminusDB, or through the Add one record
action of the Blogpost
type:
Paste the below JSON-LD definition for the blogpost. Note that @context
and @id
are generated and handled internally by the TerminusDB data product. The blogpost is actually stored as a graph structure in TerminusDB, based on the schema we added.
You can see a rendered preview of the Markdown document structure, and the data in DFRNT, including the data fields. The url
and image
urls are not used in this exampel and are there more for inspiration!
{
"@type": "Blogpost",
"frontmatter": {
"@type": "Frontmatter",
"excerpt": "This is a page summary",
"slug": "blog/blogpost",
"title": "A page about a lot of things"
},
"label": "Blogpost example",
"opengraphMetadata": {
"@type": "OpenGraphMetadata",
"image": "http://localhost:8000/blog/blogpost/image.jpg",
"title": "Blogpost example",
"type": "website",
"url": "http://localhost:8000/blog/blogpost/"
},
"statement": {
"@type": "Markdown",
"markdown": "# Heading 1\n\n## Heading 2\n\n### Heading 3\n\nSome content\n\n```\nAnd some code\n```"
},
"relatedPages": []
}
Explore the data as a graph using GraphQL queries
DFRNT embeds the GraphiQL data browser to enable exploring data as a graph. A simple query for a subset of the blogpost fields is shown below. By linking documents together, the graph can be explored across document boundaries as a complete graph, but that is for another future post.
Do make use of the keyboard shortcuts such as the Ctrl+space for schema lookups of fields and types.
Leverage data product branching and history
Data products in DFRNT fully leverages the TerminusDB model, including a git-for-data workflow for knowledge graphs. The full collaboration between remote, hosted and TerminusCMS was just released, and enables you to push and pull data from your local open source TerminusDB instance to DFRNT hosted or TerminusCMS instances, clone data products and even merge and rebase your data between branches.
The git-for-data collaboration between remote and local instances is limited to smaller data products in this initial beta release. Merge and rebase does not depend on data product size and as they are executed directly between branches in the same instance.
Start the Gatsby development server
Now we are ready to start Gatsby up and with the GraphQL endpoint and Token correctly wired up, you should be able to see it at http://localhost:8000/blog/blogpost
npm install
# npx gatsby clean ## Sometimes needed to clean out old schema and things from Gatsby
npx gatsby develop
The GraphQL link to TerminusDB is not a live connection due to current GraphQL limitations in Gatsby. You unfortunately need to restart gatsby between content updates in TerminusDB.
Build a static website that can be uploaded to a webserver
To build the website into a statical version, build gatsby and take the public
folder and upload to your favourite webserver.
npx gatsby build
Conclusion
Building websites from a TerminusDB Data Product in DFRNT enables full content schema flexibility and to build websites directly from connected data. You can publish your data in the shape the data is in, and keep full history through the git-for-data properties exposed by DFRNT.
Using branching, you could publish each branch separately, and enable content flows using git-for-data merge and rebase as content moves into higher environments, use your creativity!
By leveraging the DFRNT data modeller, data can be expressed in any shape with clear definitions. With the DFRNT GraphQL data browser, you can explore your data as a graph. Building a website from your linked data does not have to be rocket science.