The JAMStack is becoming more and more common for building out websites due to its better performance, low cost, high security, and positive developer experience.
A great solution to building a site using the JAMStack is to use Gatsby along with Netlify CMS. This post explains what the JAMStack is, how Gatsby and Netlify CMS work and provides a walkthrough for a web app built with Gatsby and Netlify CMS.
What is the JAMStack?
The JAMStack refers to a web application that has no server-side component to it, but rather relies on templated markup files which are requested through an API by client-side JavaScript to render content on a page. All of the templated markup is generated prior to deployment so there is no waiting for pages to be built on the fly as is the case for dynamic websites.
Gatsby and Netlify CMS
Gatsby is a static site generator that uses React.js as well as GraphQL. Gatsby generates a bunch of JavaScript and CSS files split up in such a way that a page will load the smallest amount of code possible to keep loading times to a minimum. GraphQL is used to query data from the Markup files into the React component files.
Netlify CMS is able to provide the Markup data for a Gatsby website. Netlify CMS allows a user to enter content through an intuitive and easy to use interface which will then get used by Gatsby to create the appropriate pages for a web app. When saving content on Netlify CMS, the data gets saved into the web application’s git repository as markdown files.
After Gatsby has generated all web app files from its build process, the web app can then be deployed to a static website host such as Netlify, Now, or Amazon S3.
Walkthrough
This walkthrough will explain the main parts of a web app built with Gatsby and Netlify CMS. This walkthrough is based on an example web app created for a fictional JavaScript meetup group.
You can view the source code for the web app on Github and you can easily deploy your own instance of the app by clicking the “Deploy to netlify” button in the README. Clicking the “Deploy to netlify” button will direct you to Netlify’s website where it asks you to connect to your Github account so that it can clone the repository and then deploy an instance of the web app. I’d encourage you to use this “Deploy to netlify” button while following along with this walkthrough if you’d like to be able to access and explore the Netlify CMS yourself.
These are some of the steps to quickly deploy an instance of the existing web app.
Accessing the CMS
To be able to access the Netlify CMS at the /admin route of the site, we’ll need to enable Netlify’s Git Gateway through their Identity service. Git Gateway allows a user to have contributors added to the CMS without giving them full access to the code repository. Netlify’s Identity service handles all of the authentications and provides an interface for user management.
The next steps are to enable Identity in the Netlify dashboard, invite yourself as a user, and then enable the Git Gateway.
Go ahead and click that “Enable Identity” button in the Netlify dashboard.
Next, click the “Invite users” button and invite yourself to be a user.
Make sure you “Enable Git Gateway” to allow Netlify to interface with your Github repository.
After inviting yourself and enabling the Git Gateway, you should have received an email inviting you to create a user for the app. After creating a user, you should be able to access the Netlify CMS for the web app by accessing the /admin route for your site and then logging in with the email and password you’ve just signed up with.
If you’re trying to find what the domain is used for the web app you deployed with Netlify, it can be found at the top of the overview page in the Netlify Dashboard.
In my case, I’ve customized the domain in settings to be gatsby-netlify-cms-example.netlify.cms. Therefore, the way I would access my app’s admin is by going to https://gatsby-netlify-cms-example.netlify.com/admin.
Accessing https://gatsby-netlify-cms-example.netlify.com/admin for the web app prompts a user to login with a username and password as shown here.
Exploring the CMS
After authenticating into Netlify CMS there should be a page displaying the site’s collections on the left and a list of latest meetups on the right. All of the data that is inputted through the CMS will get stored into a Git repository when saved. Once there is a new commit to the Git repository, Netlify will trigger a Gatsby build of the app and then deploy the app with the new content (this is called continuous deployment).
A nice thing about Netlify CMS, is that you are able to have a live preview of your page while editing content in the CMS. Setting up the preview requires a bit of thought when setting up the React code and I also haven’t had luck in having images display immediately after uploading them, but it works decently well considering the complexities involved with displaying a live preview for a static site.
The app has been coded in such a way that all of the content that gets displayed on the website can be configured in the CMS (even the navigation bar and footer content)!
Here, we will be adding/editing a new meetup entry through the CMS.
Now, we can edit the footer through the CMS.
Project structure
Let’s take a look at the code.
The project has two folders: src/ and static/.
The src/ directory contains all of the React components and Sass files that determine the app’s UI. The src/ directory also holds the markdown files holding all text and data inputted into the CMS. When data is saved in the CMS, that data gets added inside of this src/ directory in the form of markdown files.
The static/ directory contains the images or files uploaded through the CMS as well as the CMS config. The CMS config file is a config.yaml file that determines the type of data that can be added through the CMS interface.
For example, config.yaml is where you would specify that you want to define a collection called “meetups” and that each meetup should have a title, date, list of presenters, and location associated with it. Read the documentation for more info on the configuration file.
...
collections:
- name: "meetups"
label: "Meetups"
description: "Meetup dates, location, and presenter information."
folder: "src/pages/meetups"
create: true
fields:
- { label: "Template Key", name: "templateKey", widget: "hidden", default: "meetup" }
- { label: "Title", name: "title", widget: "string" }
- { label: "Date", name: "date", widget: "datetime" }
- {
label: Presenters,
name: presenters,
required: true,
widget: list,
fields:
[
{ label: Name, name: name, required: true, widget: string },
{
label: Presentation Title,
name: presentationTitle,
required: false,
widget: string,
},
...
The type of data that can be added to the CMS is specified by the configuration of data in the config.yaml file.
Getting data in React Components
Gatsby is set up to use GraphQL to query for data inside of JavaScript files and turn into React components. When looking at a React page template file, you will see a GraphQL query at the bottom of the file which queries all of the data required for the page.
...
export const aboutPageQuery = graphql`
query AboutPage($id: String!) {
markdownRemark(id: { eq: $id }) {
html
frontmatter {
title
mainImage {
image
imageAlt
}
gallery {
image
imageAlt
}
developerGroups
organizers {
title
gallery {
image
imageAlt
name
}
}
seo {
browserTitle
title
description
}
}
}
...LayoutFragment
}
`;
The names of the queried data in the GraphQL query is based on the names of the fields provided in the config.yml file. However, some of the field names are less intuitive, such as frontmatter and markdownRemark. Fortunately, Gatsby comes with GraphiQL where you can explore all of the available data through GraphQL queries in the Gatsby application. GraphiQL also acts as a way to discover the names of all the GraphQL fields through its “Documentation Explorer”. GraphiQL can be accessed when running the web app locally (using yarn develop) and then accessing http://localhost:8000/___graphql.
Data queried with GraphQL in a React Component file allows for all of the queried data to be accessed through an object passed to the file’s exported React component.
...
const AboutPage = ({ data }) => {
const { markdownRemark: page, footerData, navbarData } = data;
const {
frontmatter: {
seo: { title: seoTitle, description: seoDescription, browserTitle },
},
} = page;
return (
<Layout footerData={footerData} navbarData={navbarData}>
<Helmet>
<meta name="title" content={seoTitle} />
<meta name="description" content={seoDescription} />
<title>{browserTitle}</title>
</Helmet>
<AboutPageTemplate page={{ ...page, bodyIsMarkdown: false }} />
</Layout>
);
};
AboutPage.propTypes = {
data: PropTypes.object.isRequired,
};
export default AboutPage;
...
The exported AboutPage
component receives data provided by a GraphQL query.
The above code is a React component for the About page. Notice how the above React component for the AboutPage template has a child component of AboutPageTemplate. The reason for having a child component to the AboutPage component is so that the AboutPageTemplate component can be exported and used to set up the About page’s preview that gets shown in the CMS. This is what was eluded to earlier when saying that the CMS preview feature requires a bit of thought during the setup of the React project.
Developing locally and deploying
Running the web app locally is as simple as installing the project dependencies (yarn) and then running the start script (yarn develop).
Running the start script makes the site accessible at http://localhost:8000/.
One thing to remember while developing is that once content has been added or modified through the CMS, you will need to run git pull locally to fetch the latest changes from the CMS.
Deploying any updates to the code to the live web app is as simple as pushing new commits to your remote git repository since Netlify will automatically build the app (yarn build) and serve the updated code.
When deploying, it’s a good idea to make sure the build script ran successfully because there may be some errors if some modifications have been made related to the structure of the data expected from the CMS. If the build fails, you will need to read the error message to see why the script failed to build the app and then make adjustments accordingly.
Conclusion
If you’re interested in learning more about how Gatsby and Netlify CMS work together, you can explore the source code for the above example application, refer to the Gatsby and Netlify CMS documentation, as well as look at a starter template for Gatsby and Netlify CMS.
Plug: LogRocket, a DVR for web apps
LogRocket is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single page apps.
The post Gatsby & Netlify CMS: a perfect pairing appeared first on LogRocket Blog.
Top comments (1)
Hi! thanks for your article. I'm trying Gatsby + Netlify CMS and I'm having a problem using graphql.
I created a collection for the cateogories of my posts and I added an image field, however, I cannot seem to find the image field of the category as I would like to display a heading with a category specific image on each page. Any suggestions?