How Do I Develop My Blog

Posted on: December 3, 2023
5 min read
How Do I Develop My Blog

Motivation

Since my college days, I’ve been thinking of starting my own blog website. Prior to this project, I attempted to create a blog application with React and Golang. However, it becomes progressively complex with the addition of many unneeded features.

As developers, we know that creating a great user experience is key when building a website. And what do users love more than anything? Fast websites that don’t waste their time. With Astro, we can achieve that by shipping less code to the browser.

Why Astro?

In short, Astro is a powerful web framework for building content-driven websites like blogs, marketing, and e-commerce. Astro is best-known for pioneering a new frontend architecture to reduce JavaScript overhead and complexity compared to other frameworks. If you need a website that loads fast and has great SEO, then Astro is for you.

Creating Astro project

Astro has a CLI tool that will help you get up and running in seconds. Run the following command and follow the CLI wizard.

# create a new project with npm
npm create astro@latest

# create a new project based on a GitHub repository’s main branch
npm create astro@latest -- --template <github-username>/<github-repo>

Project Structure

Inside of the project, you’ll see the following folders and files:

/
├── public/
├── src/
    ├── components/
    ├── content
    ├── blog/
    └── config.ts
    ├── layouts/
    ├── pages/
    └── index.astro
    ├── styles/
    └── utils/
└── package.json

Content Collections

A content collection is any top-level directory inside the reserved src/content project directory, such as src/content/newsletter and src/content/authors. Only content collections are allowed inside the src/content directory. This directory cannot be used for anything else.

// 1. Import utilities from `astro:content`
import { z, defineCollection } from "astro:content";

// 2. Define a `type` and `schema` for each collection
const blogCollection = defineCollection({
  type: "content",
  schema: ({ image }) =>
    z.object({
      title: z.string(),
      description: z.string(),
      date: z.date(),
      cover: image()
        .refine((img) => img.width >= 720, {
          message: "Cover image must be at least 720 pixels wide!",
        })
        .optional(),
      tags: z.array(z.string()).default(["others"]),
      draft: z.boolean().optional(),
      featured: z.boolean().optional(),
    }),
});

// 3. Export a single `collections` object to register your collection(s)
export const collections = {
  blog: blogCollection,
};

Frontmatter

Frontmatter is the main place to store some important information about the blog post (article). Frontmatter lies at the top of the article and is written in YAML format. Read more about frontmatter and its usage in astro documentation.

Here is the list of frontmatter property for each post.

PropertyDescriptionRemark
titleTitle of the post. (h1)required*
descriptionDescription of the post. Used in post excerpt and site description of the post.required*
datePublished date.required*
coverCover image of the post.default = none
tagsRelated keywords for this post. Written in array yaml format.default = others
draftMark this post ‘unpublished’.default = false
featuredWhether or not display this post in featured section of home pagedefault = false

Only title, description and date fields in frontmatter must be specified.

Title and description (excerpt) are important for search engine optimization (SEO) and thus we encourage to include these in blog posts.

If you omit tags in a blog post (in other words, if no tag is specified), the default tag others will be used as a tag for that post. You can set the default tag in the /src/content/config.ts file.

// src/content/config.ts
export const blogSchema = z.object({
  // ---
  draft: z.boolean().optional(),
  tags: z.array(z.string()).default(["others"]), // replace "others" with whatever you want
  // ---
});

Writing a post

Here is the sample frontmatter for a post.

# src/content/blog/sample-post.md
---
title: The title of the post
description: This is the example description of the example post.
data: 2023-01-01
cover: ""
tags:
  - some
  - example
  - tags
featured: true
draft: false
---

Headings

There’s one thing to note about headings. The blog posts use title (title in the frontmatter) as the main heading of the post. Therefore, the rest of the heading in the post should be using h2 ~ h6.

This rule is not mandatory, but highly recommended for visual, accessibility and SEO purposes.

Storing Images for Blog Content

Here are two methods for storing images and displaying them inside a markdown file.

Note! If it’s a requirement to style optimized images in markdown you should use MDX.

You can store images inside src/assets/ directory. These images will be automatically optimized by Astro through Image Service API.

Example: Suppose you want to display example.jpg whose path is /src/content/blog/_images/example.jpg.

![something](./_images/example.jpg)

<!-- Using img tag or Image component won't work ❌ -->
<img src="@assets/images/example.jpg" alt="something">
<!-- ^^ This is wrong -->

Technically, you can store images inside any directory under src. In here, src/assets is just a recommendation.

Inside public directory

You can store images inside the public directory. Keep in mind that images stored in the public directory remain untouched by Astro, meaning they will be unoptimized and you need to handle image optimization by yourself.

For these images, you should use an absolute path; and these images can be displayed using markdown annotation or HTML img tag.

Example: Assume example.jpg is located at /public/assets/images/example.jpg.

![something](/assets/images/example.jpg)

<!-- OR -->

<img src="/assets/images/example.jpg" alt="something">

Deploy the Site to Cloudflare Pages

Prerequisites

To get started, you will need:

  • A Cloudflare account.
  • Push your code to a Github repository.

Deploy the site with Git

  1. Log in to the Cloudflare dashboard and select your account in Account Home > Pages.
  2. Select Create a new Project and the Connect Git option.
  3. Select the git project you want to deploy and click Begin setup
    • Framework preset: Astro
    • Build command: npm run build
    • Build output directory: dist
  4. Click the Save and Deploy button.