Create a Full-Stack Website with Strapi Headless CMS and GatsbyJS

Building modern, full-featured websites requires both a powerful frontend framework and a flexible backend content management system (CMS). By combining Strapi, the leading open-source headless CMS, with Gatsby, the blazing-fast static site generator, developers can create full-stack web applications quickly using a predominantly JavaScript-based stack.

In this in-depth guide, we‘ll walk through building a complete portfolio website using Strapi for the backend CMS and Gatsby for the frontend. We‘ll cover everything from initial setup to deployment, with plenty of code examples along the way. By the end, you‘ll have the knowledge and resources to build your own impressive full-stack websites with this potent combination of tools.

An Introduction to Strapi and GatsbyJS

Before diving into building our example project, let‘s take a moment to introduce the two key technologies we‘ll be using.

Strapi is the leading open-source headless CMS. It provides a flexible, entirely JavaScript-based backend that makes it simple to create and manage content via a feature-rich admin panel and a powerful API. Strapi is database agnostic, with support for SQLite, MongoDB, MySQL, Postgres and more. It has a strong community and addon ecosystem powering over 50,000 production sites and apps.

GatsbyJS is a popular React-based static site generator and web app framework. It allows developers to create extremely fast websites by generating static HTML, CSS, and JavaScript files from React components and content pulled from data sources like APIs, markdown, and more. Gatsby has an extensive plugin system that makes it easy to interface with CMSs, optimize assets, and drop in additional functionality.

Why Use Strapi and Gatsby Together?

On their own, both Strapi and Gatsby are powerful, flexible tools for creating websites and web apps. When combined, however, they open up even more possibilities:

  • Since both are based on JavaScript and Node.js, developers can use a single language across the entire stack
  • Gatsby‘s static site generation pairs perfectly with Strapi‘s API-delivered content for incredibly fast page loads and excellent SEO
  • Strapi‘s self-hosted, open-source nature provides complete control and portability, while Gatsby allows the frontend to be hosted almost anywhere
  • The two communities are very active and have created many plugins, starters, and tutorials to help developers hit the ground running

With introductions out of the way, let‘s get to the fun part – actually building something!

Creating a Portfolio Site with Strapi and Gatsby

To illustrate how Strapi and Gatsby work together, we‘ll create a simple portfolio site. It will have multiple pages showcasing projects, allow toggling between light/dark mode, include a contact form, and support content managed via Strapi. This mirrors a real-world use case and touches on many of the key features of both platforms.

Setting Up the Strapi Backend

First, we need to get our Strapi backend set up. Assuming you have Node.js installed, create a new directory for the project and initialize Strapi:

mkdir portfolio-project && cd portfolio-project
npx create-strapi-app backend --quickstart

This will scaffold a new Strapi project in a "backend" directory, install dependencies, and start the Strapi server at http://localhost:1337. Navigating there in your browser will take you through the initial setup steps, including creating an admin user.

With the server running, we can create a content type to hold our portfolio projects. In the Strapi admin panel, navigate to "Content-Types Builder" under the "Plugins" menu. Click the "Create new collection type" button and fill in a name like "project". Add whatever fields you‘d like your projects to have – perhaps a text field for the title, a rich text area for the description, an image for a screenshot, and so on.

After saving the content type, we can navigate to "Content Manager" and start creating some actual projects. Go ahead and add a few to have some data to work with on the frontend.

Querying Strapi from Gatsby

With some content created in Strapi, let‘s shift to building the Gatsby frontend. Again assuming you have Node.js and the Gatsby CLI installed, use the CLI to create a new Gatsby site in the same top-level project directory as the "backend" folder:

gatsby new frontend

This creates a starter Gatsby site in a "frontend" directory. To pull in content from our Strapi backend, we‘ll need to configure the gatsby-source-strapi plugin. Install it along with the gatsby-image and gatsby-transformer-sharp plugins we‘ll use for optimized images:

npm install gatsby-source-strapi gatsby-plugin-image gatsby-plugin-sharp

Then add the following to your gatsby-config.js:

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-strapi`,
      options: {
        apiURL: `http://localhost:1337`,
        queryLimit: 1000,
        collectionTypes: [`project`],
        singleTypes: [],
      },
    },
    `gatsby-plugin-image`,
    `gatsby-plugin-sharp`,
    `gatsby-transformer-sharp`,
  ]
}  

This configures the Strapi plugin to pull in data from our local Strapi server, and makes the image processing plugins available.

Now we can query our project data from Gatsby pages and components using GraphQL. For example, to display a list of project titles on the homepage:

import React from "react"
import { graphql } from "gatsby"

export default function Home({ data }) {
  return (
    <div>

      <ul>
        {data.allStrapiProject.edges.map(project => (
          <li key={project.node.id}>{project.node.title}</li>
        ))}
      </ul>
    </div>
  )
}

export const query = graphql`
  query {
    allStrapiProject {
      edges {
        node {
          id
          title
        }
      }
    }
  }
`

By exporting a query constant from our page, Gatsby will execute that GraphQL query and surface the results in the data prop. We then use standard React code to render the data as desired.

For more complex page structures, we can use Gatsby‘s createPages API to programmatically create pages from our Strapi data. For example, to create an individual page for each project:

// gatsby-node.js
const path = require(`path`);

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions;
  return graphql(`
    {
      allStrapiProject {
        nodes {
          title
          slug
          description
          id
        }
      }
    }
  `).then((result) => {
    result.data.allStrapiProject.nodes.forEach((node) => {
      createPage({
        path: node.slug,
        component: path.resolve(`./src/templates/project.js`),
        context: {
          slug: node.slug,
        },
      });
    });
  });
};

This queries all projects from Strapi and for each one, creates a new page at a path matching the project‘s slug. The actual page is defined in a project.js template component, which receives the slug via the context object and can use that to query for the full details of an individual project.

Going Further with Gatsby

With data flowing from Strapi to Gatsby, we‘ve got the foundations of a full-stack site in place. From here, we can leverage Gatsby‘s rich ecosystem to add additional features and polish.

Some examples of what you might add:

  • Use the gatsby-plugin-styled-components or gatsby-plugin-emotion plugins to enable CSS-in-JS for styling components
  • Integrate gatsby-plugin-mdx to author content in Markdown/MDX instead of or in addition to Strapi
  • Drop in gatsby-plugin-google-analytics for usage tracking
  • Style your contact form and submit the data to a service like Formspree using Gatsby‘s onSubmit form handler
  • Use the gatsby-plugin-sitemap and gatsby-plugin-robots-txt plugins for SEO
  • Leverage gatsby-plugin-offline to add a service worker for offline support

The possibilities are nearly endless. Gatsby‘s plugin library has solutions for most common needs, and you can always write your own for custom functionality.

Deployment and Beyond

With our Strapi-backed Gatsby site built, the final step is deploying it for the world to see. The specifics will depend on your hosting setup, but there are a few common patterns.

For the frontend, static hosting services like Netlify and Vercel are popular choices. They connect to your Git repository, automatically build your Gatsby site whenever you push changes, and serve the resulting static files from a global CDN. Configuration is minimal, and the generous free tiers are sufficient for most small to medium sites.

The Strapi backend can be deployed to any server or cloud platform that supports Node.js. For ease of setup, the Strapi team maintains one-click deploymemt options for hosting providers like Heroku, DigitalOcean, AWS, and more. For larger, high-traffic sites, you might opt to Dockerize Strapi and deploy it to a Kubernetes cluster for maximum scalability.

Once deployed, be sure to update your Gatsby config to pull data from your production Strapi URL instead of localhost. You‘ll also want to configure Strapi‘s admin panel, content API permissions, and other security measures appropriately for a public-facing site.

Learning More

This guide covered the essentials of using Strapi and Gatsby together to build a full-stack site, but there‘s always more to learn. To dive deeper, check out these resources:

  • The official Strapi and Gatsby documentation
  • Strapi and Gatsby tutorials on platforms like Scotch.io, Snipcart, and Stackbit
  • The Strapi and Gatsby communities on Discord, Reddit, StackOverflow, and more
  • Strapi and Gatsby starters and example projects on GitHub
  • Course platforms like Udemy, Pluralsight, and egghead for video-based Strapi and Gatsby learning

With its powerful combination of flexible content management and lightning-fast static site generation, the Strapi + Gatsby stack has a lot to offer to developers of all skill levels. We hope this guide has inspired you to give it a try for your next web project!

Similar Posts