Supercharge Your Technical Blog: Gatsby, TypeScript & Sanity — Free & Fabulous!

Aleksei Volkov
6 min readMar 17, 2023

Technical blogging has become a popular way for developers to establish their expertise. When searching online, many results lead to personal blogs. Front-end leaders such as Kent C. Dodds and Dan Abramov have their own technical blogs. They use headless CMS platforms without incurring hosting fees.

In this article, I will guide you through steps of building your own technical blog. I will use headless CMS platforms like Sanity.io and deploy it for free on services such as Netlify. Front end will use GatsbyJS with TailwindCSS. I am Aleksei, 3 years of React experience, working in Luxoft.

Screenshot of minimal technical blog
Dev blog example — gatsby.js.garden

Backend

When it comes to building a personal blog, the question of how to store articles often arises. Traditional SQL databases were popular for years. But they are not the easiest to set up. They can be expensive to maintain and difficult for front-end developers.

One solution to this problem is to use Markdown (MD) files. They are easy to start with but may be difficult to extend.

Another approach is to use headless CMS solutions. For example Sanity.io. It offers a more sophisticated system for storing and managing content.

Developers can define front-end-friendly schemas. Platform will handle authentication and storing assets. Sanity.io is an attractive option for building their personal blog.

MDX

MDX is a markdown format that allows for greater flexibility and interactivity. Developers can use JSX in their markdown content. This opens up possibilities for interactive charts or alerts in their posts.

MDX 2 takes this even further. Offering new features such as new builders support and improved AST. MDX offers a powerful and flexible solution for storing and displaying content on the web.

Learn how to use it in your project — https://mdxjs.com/docs/

JSON

One popular approach for storing and retrieving data on the front end is to use JSON files. With the Fetch API, it’s easy to make an HTTP request to fetch the data from a JSON file. Then parse it using the built-in JSON.parse() method.

Another approach is to use the webpack json loader. https://webpack.js.org/migrate/3/#json-loader-is-not-required-anymore

Both of these approaches are popular in modern front-end development. They provide an easy way to store and access data on the client side.

Sanity

Sanity.io is a powerful headless CMS . It’s a set of tools for creating efficient, data-driven content applications. Sanity Studio is an administration panel. It connects to Sanity servers and stores all your data and schemes.

Studio is a GitHub repo that installs locally, and it handles all the backend work for you. You describe instances of your database as simple TypeScript objects.

Content Lake is a set of backend tools for storing your data. So you don’t hassle of managing images or setting up MySQL databases for your website.

While Sanity is often used for pulling data, pushing data is also possible. Find a quick rundown of how to get started with Sanity below.

TypeScript schema

If you want to build a Sanity project using TypeScript, you can do it with the help of the command line interface. To get started, run the command “npm create sanity@latest” in your terminal.

This will prompt you with a series of questions. Select TypeScript as your language and the appropriate template. Now you can start writing your schemas.

export default {
name: 'post',
title: 'Articles',
type: 'document',
fields: [
{
name: 'title',
title: 'Title',
type: 'string',
},
// custom type "blockContent" should be described in relative file
{
name: 'content',
type: 'blockContent',
title: 'Content',
},
],
}

Schemas define the structure of your data and the way it stores in Sanity’s Content Lake. You can use TypeScript interfaces to define your schema types. Check official schema example.

Portable Text

Sanity doesn’t offer a WYSIWYG editor. There is a Portable Text. It. lets you use a rich text editor and output clean HTML.

Portable Text is a JSON-based specification. It stores rich text as an array of blocks and custom types. Treat content as agnostic instances like bold text, images, and links. You may edit them with a unified editor in Sanity Studio. Then output with any design needed. Find my schema for Sanity content editor below.

export default {
title: 'Block Content',
name: 'blockContent',
type: 'array',
of: [
{
type: 'block',
title: 'Block',
styles: [
{title: 'Normal', value: 'normal'},
{title: 'H1', value: 'h1'},
],
// Marks let you mark up inline text in the block editor.
marks: {
// Decorators usually describe a single property – e.g. a typographic
// preference or highlighting by editors.
decorators: [
{title: 'Strong', value: 'strong'},
{title: 'Underline', value: 'underline'},
],
},
},
{
type: 'code',
name: 'code',
title: 'Code Highlighting',
options: {
language: 'javascript',
languageAlternatives: [
{title: 'TypeScript', value: 'typescript'},
{title: 'JSON', value: 'json'},
],
withFilename: true,
theme: 'monokai',
},
},
],
}

Deploy

Deploying Sanity is a flexible process that can suit different needs. Launch Sanity locally for development purposes. When it’s time to go live, there are different deployment options available.

Deploy Sanity to your own server or to a cloud provider. Or, use Sanity’s own hosted service. It takes care of the infrastructure and provides extra features.

Frontend

There are various front-end solutions available for using Sanity as a headless CMS.

Create React App

Generate a new React project with Create React App. It is a set of pre-configured dependencies. It is a quick way to get started with building a front-end application that consumes data from Sanity.

GatsbyJS

Gatsby JS enables developers to build performant and optimized websites. It leverages modern web technologies, such as React and GraphQL. This also integrates well with Sanity through the Gatsby source plugin.

Typescript Template

Simplify starting a GatsbyJS project using the Gatsby CLI. Use “gatsby new” command to scaffold a new project with basic file structure and dependencies. There are official guidelines but you need to install it manually for better control.

`npm init gatsby`

Use the Gatsby source plugin for Sanity to connect your Gatsby site with your Sanity backend. Check gatsby-node file for dynamically creating pages from sanity, index page and single post template.

TailwindCSS

TailwindCSS is a popular utility-first CSS framework. It offers a range of pre-built classes that can compose to any design. It’s like Bootstrap, but with the added advantage of CSS tree shaking. That means only the styles you use in your project will be in the final CSS. TailwindCSS includes a basic browser CSS reset. Moreover it offers classes like flex, pt-4, text-center, and rotate-90 for easy styling in your markup.

Tailwind founder article about css approaches

<!-- Bare minimum stylings for blog -->
<body className="prose lg:prose-xl font-serif mx-8 my-4" />

Portable text

Code highlighters allow developers to add syntax highlighting to code snippets. Place them in blog posts or websites.

One popular code highlighter is react-refractor. It is a thin wrapper on top of the refractor library. refractor is a lightweight and elegant virtual syntax highlighter that uses Prism. It doesn’t inject CSS for the syntax highlighted code, but in a browser, you can use any Prism theme.

Portable Text provides a way to store rich text content as an array of blocks and custom block types. It outputs semantic HTML through a range of frontend frameworks and surfaces. Style raw HTML using Tailwind Prose plugin. Portable Text have a raw JSON representation. The field called _raw<FieldName> for top-level nodes. Check my Portable Text Parser file.

<article>
<h1>{post.title}</h1>
<small>{post.publishedAt}</small>
<p>{post.description}</p>
<PortableText value={content} components={components} />
</article>

SEO

Gatsby Head API simplifies adding elements to your page’s document head. Use it to improve site’s SEO with metadata.

// Basic Gatsby Head API usage
export function Head({
data: { site }
}: HeadProps<Queries.IndexPageQuery>): React.ReactElement {
const siteMetadata = site?.siteMetadata

return (
<>
<title>{siteMetadata?.title}</title>
<body className="prose lg:prose-xl font-serif mx-8 my-4" />
</>
)
}

export const query = graphql`
query IndexPage {
site {
siteMetadata {
title
description
}
}
}
`

Links

--

--