Table of contents
- Some background story
- Getting started with Astro
- Astro component system
- Folder structure
- Astro plugins
- Conclusions
Some background story
I had been planning to work on my own website for a few years but never got round to it since I was always so busy with work. This year I took some time off to rest and learn new things. One day I came across the Astro framework at https://astro.build.
They advertise the framework with the following slogan “Astro is a JavaScript web framework optimized for building fast, content-driven websites”. I thought I’d give it a try since I wanted to build a blog and practise coding in new technologies at the same time. I had tried using the Remix framework before, but it seemed too complex for what I needed to achieve. I just wanted a content-driven website with some basic functionality and not a full-blown application at this point. It turns out that Astro is perfect for my needs.
Getting started with Astro
It wasn’t difficult to start. All I needed was to have npm installed and to follow the tutorial on the website.
One command and off we go to the races.
npm create astro@latest -- --template minimal
I chose the minimal template for the website to build everything myself from scratch. The Astro framework works off a very simple principle that .astro files placed in the pages subfolder repesent both page content and URLs.
I use Neovim for Astro development. Astro LSP works with prettier so you need to install it in order to format .astro files.
npm install --save-dev prettier prettier-plugin-astro
The setup also requires the config file called .prettierrc.mjs in the project root folder.
/** @type {import("prettier").Config} */
export default {
plugins: ['prettier-plugin-astro'],
overrides: [
{
files: '*.astro',
options: {
parser: 'astro',
},
},
],
}
More is described on the Editor Setup page.
Astro component system
The Astro framework also has a built-in component system that allows you to create reusable components using these .astro files. Apart from that, it also has built-in support for Markdown files so writing blog articles is quite easy. Any JavaScript or TypeScript template code is placed in the top section of .astro files and is separated by dashes:
---
const title = "My new website built with Astro";
---
<h1>{title}</h1>
These .astro files also make importable components, the equivalent of partials in the Razor engine so we can stack them on top of each other and pass variable values as Astro.props (properties) up the stack as well.
import Navigation from "../../components/Navigation.astro";
import Layout from "../../layouts/Layout.astro";
---
<Layout pageTitle="Page title configured from inside the component">
<Navigation />
<main>
Hello world!
</main>
</Layout>
The Layout.astro component has access to the Astro.props object to provide values from the component below.
---
import "../styles/base.css";
const { pageTitle } = Astro.props;
---
<!doctype html>
<html lang="en">
<head>
<title>{pageTitle}</title>
Folder structure
After some trial and error, I figured out the component structure that I wanted to use for the website and the blog pages. Even the 404 error has its own page file and is automatically supported just by the file name. The file called [tag].astro is a special kind of file which receives the last segment of the url into the Astro.params object so we can read what is dynamically under the /blog/tags/[name of the tag] URL.
├── components
│ ├── AboutMe.astro
│ ├── BlogLink.astro
│ ├── BlogTags.astro
│ ├── ContactMe.astro
│ ├── Footer.astro
│ ├── FullLogo.astro
│ ├── Hamburger.astro
│ ├── Hero.astro
│ ├── HeroBlog.astro
│ ├── HeroButtons.astro
│ ├── Hr.astro
│ ├── Menu.astro
│ ├── Navigation.astro
│ └── SocialLink.astro
├── env.d.ts
├── layouts
│ ├── BlogLayout.astro
│ └── Layout.astro
├── pages
│ ├── 404.astro
│ ├── about.astro
│ ├── blog
│ │ ├── 01_astro_website.md
│ │ ├── index.astro
│ │ └── tags
│ │ └── [tag].astro
│ ├── contact.astro
│ ├── index.astro
│ └── robots.txt.ts
└── styles
└── base.css
Astro plugins
The plugin system in Astro is quite powerful and allows you to add functionality with a simple command.
npx astro add amazing-plugin-which-does-amazing-things
I wanted to use Tailwind CSS for this project so I installed the astro-tailwind plugin.
npx astro add tailwind
And that was it! It even updated the astro.config.mjs file with the Tailwind CSS configuration automatically.
I created base.css under the styles folder and I could use Tailwind’s @apply directive on my custom css classes.
.tag {
@apply rounded-xl font-bold inline-grid p-2 text-sm m-1;
@apply bg-blue-700 hover:bg-blue-900 text-white;
@apply cursor-pointer;
}
There also other plugins like astro-sitemap but the sitemap-index.xml file gets generated only with Astro builds so you won’t see it with npx astro dev. You need to run npx astro preview which previews a deployable build.
I also used remark.js built into Astro for the reading time displayed at the top of this page, and for the table of contents. You have to add the appropriate heading name from the config file to your Markdown file for the toc links to appear if you use the remark-toc plugin.
astro-icon was used for displaying vector icons.
The Markdown files support code syntax highlighting out of the box too. You just have to configure the theme that you like.
Here’s my astro.config.mjs file:
import { defineConfig } from 'astro/config';
import icon from 'astro-icon';
import tailwind from '@astrojs/tailwind';
import sitemap from '@astrojs/sitemap';
import { remarkReadingTime } from './remark.readingtime.mjs';
import remarkToc from 'remark-toc';
// https://astro.build/config
export default defineConfig({
site: 'https://www.rafalbielec.com',
markdown: {
remarkPlugins: [remarkReadingTime, [remarkToc, { heading: 'Table of contents', maxDepth: 3 }]],
shikiConfig: {
themes: { light: "github-dark", dark: "github-dark" },
},
}, integrations: [sitemap(), icon(
{
iconDir: 'src/icons',
}), tailwind()],
});
Conclusions
Overall I am extremely happy with Astro! It took me few days to learn a new framework, style a new website with my own design from scratch, set up the URL structure for this simple blog site, and use the built-in features which I would have to configure manually from different libraries all over the Internet. I even configured Google Analytics in a matter of seconds with a quick look-up of this article How to add GA4 and Google Tag Manager to your Astro Website.
In conclusion, it’s a yes from me. I highly recommend Astro for your next content-driven site, and I’ll keep on posting articles on this blog in Markdown. I started with Remix but I ended up with a framework which had never heard of before.