How we use Strapi for our blog.

This blog has used several methods for content: WordPress, Gatsby, Ghost, Jekyll, Camel.

When we relaunched this site, we chose to use next.js. With that, several pages including our docs are now in markdown.

But for the blog, we chose to use Strapi.

Strapi is set up so that we use GraphQL to statically generate posts on deployment, but we can also choose to add some dynamics such as searching.

We created a post content type in our Strapi solution with the following fields:

  1. Title
  2. Date
  3. State
  4. Content
  5. Excerpt
  6. CoverImage

When we publish a new post, we trigger a webhook at Vercel which triggers a deployment and regeneration of our blog page along with the blog post's page.

We use this GraphQL query to return posts for our main blog page:

export async function getAllPostsForHome(preview) {
  const data = await fetchAPI(
    `
    query Posts($where: JSON){
      posts(sort: "date:desc", limit: 100, where: $where) {
        title
        slug
        excerpt
        date
        coverImage {
          url
        }
      }
    }
  `,
    {
      variables: {
        where: {
          { status: 'published' },
        },
      },
    }
  )
  return data?.posts
}

This will return up to 100 blog posts, sorted by their date.

Then in pages/blog/index.js, we include the following:

export async function getServerSideProps({ params, preview = null }) {
    const allPosts = (await getAllPostsForHome(preview)) || []
    return {
        props: { allPosts },
    }
}

This then lets us render the posts, also in pages/blog/index.js:

import Link from 'next/link'

export default function Index({ allPosts }) {
  return (
    <>
          {allPosts.map( (post, i) => (
                  <Link key={i} href={`/blog/{post.slug}`} />{post.title}</Link>
           )) }
    </>
  )
}

Then to grab the post in the post's single page, we use this query:

export async function getPostAndMorePosts(slug, preview) {
  const data = await fetchAPI(
    `
  query PostBySlug($where: JSON) {
    posts(where: $where) {
      title
      slug
      content
      date
      coverImage {
        url
      }
    }
  `,
    {
      variables: {
        where: {
          slug,
          status: 'published',
        },
      },
    }
  )
  return data
}
`

This returns the post by slug, We'd then create a page called pages/blog/[slug].js:

import Head from 'next/head'
import Link from 'next/link';
import Markdown from "react-markdown";

export default function Post({ post }) {
    return (
      <>
          <h1>{post.title}</h1>
            <Markdown source={post.content} escapeHtml={false} />
      </>     
    )
}

export async function getStaticProps({ params}) {
    const data = await getPostAndMorePosts(params.slug)

    return {
        props: {
            post: {
                ...data?.posts[0],
            },
        },
    }
}

export async function getStaticPaths() {
    const allPosts = await getAllPostsWithSlug()
    return {
        paths: allPosts?.map((post) => `/blog/${post.slug}`) || [],
        fallback: true,
    }
}  

That's it, that's how we use Strapi for our blog. as it gives us a nice CMS for posts.

Ready To Build Awesome Apps?
Get started for free