Gatsby blog in a Monorepo, created from scratch, with some requirements

I am trying to create a Gatsby blog as a part of Monorepo, with /data and /dist (output-dir) directories sticking out, instead of being inside the Gatsby repo.

I also created this from scratch, partly by following https://www.freecodecamp.org/news/build-a-developer-blog-from-scratch-with-gatsby-and-mdx/

Background

Actually, I have already created this kind of blog/cli concept with Nuxt and Vue, but I am starting to dislike *.vue and starting to love *.tsx -- so, I am giving React another chance. (Also knowing that Preact is smaller and almost as performant as Vue.)

I have also tried Gridsome, which is in many ways similar to Gatsby, in the sense of GraphQL -- but not equally well supported, though…

Requirements

  • Write blog posts using Markdown with YAML front-matter -- passed
  • Markdown must be customizable -- passed
  • Customizable excerpt, instead of always cut at 140 chars -- passed
  • Searchable, using a search bar, that is /post?q=<SEARCH_STRING> works -- might fail, but I will try
  • Recent posts' view -- obviously passed
  • Hidden posts, but viewable, if you have a link -- passed, probably with hidden: true or published: false in YAML front matter
  • Recent posts mean < Date.now(). All posts in the future must be hidden, but will auto-show when the time comes -- passed, as long as I create it myself, unlike Jekyll
  • Custom page type, e.g. Reveal-md -- should pass, as I create this myself

Why

  • Gatsby should be fast. Also SEO optimized with some additional settings, or perhaps with Helmet
  • It's more than SEO, really. I also need a correct preview on Facebook / Twitter / Discord.
  • To write a blog while seeing Gatsby's folder structure is a turn off. Seeing only /data is so focused mode.
  • Sharing themed blog is easy, because it is just a part of the monorepo. Writing .gitignore is easy as well.
  • I can always author subpackages, like, probably, a newer version of q2filter. Testing is easier than ever with a monorepo.

First impressions

  • GraphQL is magical.
  • Much is already done by Gatsby and plugin creators. (Unlike Gridsome)
  • I can always play with queries in the browser. (Not sure if it is the case with Gridsome)
  • React have gotten simpler by Function Components and React hooks.
  • I will probably use @emotion/core. Have tested it is another repo.
  • Many more VSCode plugins are needed/helpful,
  • GraphQL
  • Highlight Matching Tag
  • lit-html
  • Styled components

How I create from scratch

  • lerna init + eslint --init at root and install ESLint settings at root, to avoid cluttering subpackages.
  • mkdir packages/gatsby-blog-cli && cd packages/gatsby-blog-cli && yarn init -y
  • Minimal packages for Gatsby are
  • React
  • React-dom
  • Gatsby
  • Minimal packages for Blog are
  • gatsby-transformer-remark
  • Packages for externalizing /data and /media are
  • gatsby-plugin-static-folders
  • fs-extra
  • By default, Gatsby cannot yet choose output folder [issue], must be solved with a postbuild script.
  • Creating cli.js is quite simple. Don't forget to add "bin" to package.json
{
  "bin": {
    "blog": "cli.js"
  },
}
  • Reading an external config.yaml is quite complex, as it might need validation.
  • Create gatsby-config.js
const siteMetadata = require('./config')

module.exports = {
  siteMetadata,
  plugins: [
    {
      resolve: 'gatsby-transformer-remark',
      options: {
        excerpt_separator: '===',
      },
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        path: `${process.env.ROOT}/posts`,
        name: 'posts',
      },
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        path: `${process.env.ROOT}/hidden`,
        name: 'hidden',
      },
    },
    {
      resolve: 'gatsby-plugin-static-folders',
      options: {
        folders: [
          `${process.env.ROOT}/media`,
        ],
      },
    },
  ],
}

Apparently, I haven't finished yet, so I will update soon, also with minimalism, in the repo

Part 2