In this tutorial, I will show you how to use TakeShape as a CMS in your Gatsby site using gatsby-source-takeshape by building a Portfolio app. Let's get started!
What is TakeShape?β
TakeShape is a set of services that powers Jamstack projects of any size or complexity. In this tutorial, I will use TakeShapeβs GraphQL API and Editor UI as a CMS to manage portfolio content. This will allow us to query data from out Gatsby app.
Prerequisitesβ
This tutorial assumes that you have basic experience with Gatsby and GraphQL.
Setting upβ
To create a new Gatsby site, you need to open your command-line-interface (CLI) and run this command:
npx gatsby new gatsby-shape-gallery
This command will generate a new Gatsby project with the default starter. You can alternatively install the gatsby CLI and use the gatsby command to create a new project.
To use TakeShape with Gatsby, we need to install the gatsby-source-takeshape plugin to be able to interact with the GraphQL API. Browse to the project folder and run this command in your CLI:
yarn add gatsby-source-takeshape
Or
npm install gatsby-source-takeshape
Now let's structure the project as follows:
βββ src
βββ components
| βββ header.js
| βββ layout.css
| βββ layout.js
| βββ Project.js
| βββ seo.js
βββ images
βββ pages
| βββ 404.js
| βββ index.js
βββ routes.js
βββ templates
βββ project-template.js
βββ gatsby-browser.js
βββ gatsby-config.js
βββ gatsby-node.js
βββ gatsby-ssr.js
Here's break down the projectβs file structure:
components/Project.js
is the component that renders a single project.routes.js
contains a helper function that creates a slug for the path of each project, making it more user-friendly.project-template.js
is a template that allows the display of a full project.
With this in place, we can now create some projects on the TakeShape platform so we have data to work with.
Create the projects using TakeShapeβ
To use TakeShape as a CMS, you will need to create an account (it's free). Once you are registered, start a new project.
Select Shape Portfolio as a pattern to seed the project with data and images.
Next you'll need an API Key for your project.
To connect to your TakeShape project, you need your API Endpoint and an API key.
If you haven't created a TakeShape project yet, follow this guide to do so.
If you already have a project, your API Endpoint will be in the TakeShape web client. In the home tab, look for the "Useful Snippets" section.
Copy the API Endpoint and save it somewhere secure.
To get an API Key, you'll have to create one. Read our docs on creating an API Key here.
To generate the API keys, click on the New API Key button, set a name that suits you, and then make sure to select Dev on the Permissions field so the gatsby-source-takeshape plugin has the proper permissions. If you are seeing errors when you try to build you site, double check the API key permissions.
We now have the API keys required to retrieve data from TakeShape. In the next section weβll build the Gatsby app.
Configuring gatsby-source-takeshapeβ
First, we need to create a .env file to keep our credentials safe. If youβre committing your project to source control, like Github or Bitbucket, remember to add .env to your .gitignore so you donβt accidentally add private keys to your repo.
TAKESHAPE_PROJECT=<your-project-id>
TAKESHAPE_TOKEN=<your-api-key>
Replace the placeholder with your credentials. You can find the TAKESHAPE_PROJECT in the URL of your TakeShape project, or on the API Keys page in the endpoint URL.
require(`dotenv`).config()
{
resolve: `gatsby-source-takeshape`,
options: {
apiKey: process.env.TAKESHAPE_TOKEN,
projectId: process.env.TAKESHAPE_PROJECT,
},
},
We need to use environment variables to add the credentials to the config. You don't have to add a URL since the plugin handles everything automatically for you.
const path = require(`path`)
const routes = require(`./src/routes`)
exports.createPages = async ({ actions, graphql }) => {
const { data } = await graphql(`
query {
takeshape {
projects: getProjectList {
items {
_id
name
}
}
}
}
`)
data.takeshape.projects.items.forEach(({ _id, name }) => {
actions.createPage({
path: routes.projects(name),
component: path.resolve(`./src/templates/project-template.js`),
context: {
projectId: _id,
},
})
})
}
TakeShape uses the name of your content model (in this case βProjectβ) to create a GraphQL Type (projects
) and then provide two GraphQL queries: one for retrieving all data (getProjectList
) and another for getting a single object (getProject
).
At build time, Gatsby will query TakeShape to get the project list. Then, for each object, it will create a statically rendered page that allows the display of the full project with the template as a component.
We can now create the components and retrieve our data from TakeShape.
Creating the componentsβ
import React from 'react'
import { Link } from 'gatsby'
import Img from 'gatsby-image'
import routes from '../routes'
const Project = ({ project }) => {
const { name, coverImage, description } = project
return (
<Link to={routes.projects(name)} className='project-preview'>
<Img
className='project-preview--cover'
style={{ width: '100%' }}
fixed={coverImage.fixed}
alt={description}
/>
<h1 className='project-preview--title'>{name}</h1>
</Link>
)
}
export default Project
As you can see, we have a component that receives the fetched project as a parameter. With the project object available to our component, weβll pull out the data weβd like to display and pass the name of the project to the routes helper method, which will create a slug.
import React from 'react'
import { graphql } from 'gatsby'
import Img from 'gatsby-image'
import Layout from '../components/layout'
import SEO from '../components/seo'
const ProjectTemplate = ({ data }) => {
const {
takeshape: {
project: { coverImage, name, description },
},
} = data
return (
<Layout>
<SEO title={name} />
<article className='project'>
<header>
{coverImage ? (
<Img style={{ height: '22rem' }} fluid={coverImage.fluid} />
) : (
``
)}
<h1 className='project--title'>{name}</h1>
</header>
<div dangerouslySetInnerHTML={{ __html: description }} />
</article>
</Layout>
)
}
export default ProjectTemplate
export const query = graphql`
query($projectId: ID!) {
takeshape {
project: getProject(_id: $projectId) {
name
coverImage {
description
path
fluid(maxWidth: 1200, maxHeight: 600) {
...GatsbyTakeShapeImageFluid
}
}
description: descriptionHtml
}
}
}
`
This query will return a single object from TakeShape. As previously mentioned, the id of the project will be provided to Gatsby automatically to generate individual pages. Next, we pass the fetched data to the ProjectTemplate
component to display it.
We can now edit the index.js
file to get the data from TakeShape when the page loads.
import React from 'react'
import { graphql } from 'gatsby'
import Layout from '../components/layout'
import SEO from '../components/seo'
import Project from '../components/Project'
const IndexPage = ({ data }) => {
const {
takeshape: {
projects: { items },
},
} = data
return (
<Layout>
<SEO title='Home' />
<div className='project-container'>
{items.map((project) => (
<Project key={project._id} project={project} />
))}
</div>
</Layout>
)
}
export default IndexPage
export const query = graphql`
query {
takeshape {
projects: getProjectList {
items {
_id
name
startDate
coverImage {
description
path
fixed(width: 300, height: 200) {
...GatsbyTakeShapeImageFixed
}
}
}
}
}
}
`
As you can see, the query fetches all projects from TakeShape using GraphQL. Now we loop through the response data and for each project we use the Project
component to display it.
With this in place, we can now test the app in the browser.
Testing the appβ
To preview the app in the browser, execute the following command on the CLI.
yarn start
For npm
npm start
Or when using Gatsby CLI
gatsby develop
Now let's visit on the browser http://localhost:8000/.
And that's it! Our app is looking good!
Weβve built a nice looking portfolio site using Gatsby and TakeShape. You can find the finished code in this Github repo.
Conclusionβ
In this guide, we learned how to use TakeShape and Gatsby together with the gatsby-source-takeshape
plugin to build a simple portfolio site. Give it try on your next project!
Resourcesβ
Check out these resources to dive deeper into the content of this tutorial: