· Tomo · Web Development  · 6 min read

How I fell in love with Astro

Finally, I found a generator that fits my needs. Astro is a static site generator that combines the best of both worlds - the speed and security of static sites with the flexibility and power of JavaScript.

Finally, I found a generator that fits my needs. Astro is a static site generator that combines the best of both worlds - the speed and security of static sites with the flexibility and power of JavaScript.

Back when I started Tomoweb in 2020, I was looking for the simplest way to create a blog. I wanted to focus on writing, but still have a nice looking website. As I was just a junior then, I didn’t have much experience with web development, especially not with static site generators.

The decision fell on WordPress, as it was somewhat familiar to me. I liked the idea of having a nice environment to make content and have it SEO optimized out of the box with Yoast SEO. But as time went on, I realized that WordPress was too bloated for my needs. Additionally, I didn’t like the idea of having WordPress as its stack is not my cup of tea.

After I got bored using Gutenberg, I started looking for alternatives. Should I go with some platforms like Wix, Squarespace, or Webflow, or should I try something else? As every developer, I wanted to have as much control as possible over my website. I wanted to have a fast, secure, and SEO optimized website, but I also wanted to have the flexibility to change anything I wanted. That’s when I found Astro.

What is Astro?

To make a long story short, Astro is a JavaScript web framework that allows you to build static websites with dynamic components. It’s a static site generator that combines the best of both worlds - the speed and security of static sites with the flexibility and power of JavaScript. I found about it through my colleague, who was using it for some time. He told me that it’s definitely worth checking out, so I did…and it was love at first sight.

The framework is based on Astro components, which are a mix of technologies we already know - HTML, CSS, and JavaScript. Aside from that, Astro has support for popular JavaScript libraries like React, Vue, and Svelte. This means that you can use your favorite JavaScript library to build your website, which is a huge plus in my book. The best part is that Astro is built with performance in mind, rendering components on the server, and then delivering the static HTML to the web browser. Behind Astro there is my favorite build tool - Vite. For those who don’t know, Vite is one of the fastest builders out there, delivering blazing fast development and production builds.

Astro also likes to isolate components into “islands”. This means that each component is independent of the others, which makes it easier to reason about your code. This was another huge plus for me, as I like to keep my code clean and organized. To show you how familiar Astro components are, here is an example of my blog list item component:

---
import type { ImageMetadata } from 'astro';
import { Icon } from 'astro-icon/components';
import Image from '~/components/atoms/Image.astro';
import PostTags from '~/components/atoms/Tags.astro';

import { APP_BLOG } from 'astrowind:config';
import type { Post } from '~/types/post';

import { getPermalink } from '~/utils/permalinks';
import { findImage } from '~/utils/images';
import { getFormattedDate } from '~/utils/dates';

export interface Props {
  post: Post;
}

const { post } = Astro.props;
const image = (await findImage(post.image)) as ImageMetadata | undefined;

const link = APP_BLOG?.post?.isEnabled ? getPermalink(post.permalink, 'post') : '';
---

<article class={`w-full grid gap-6 md:gap-8 ${image ? 'md:grid-cols-2' : ''}`}>
  {
    image &&
      (link ? (
        <a class="card group relative block h-fit w-full" href={link ?? 'javascript:void(0)'}>
          <div class="relative h-0 overflow-hidden bg-background-hihglighted pb-[56.25%] md:h-72 md:pb-[75%] lg:pb-[56.25%]">
            {image && (
              <Image
                src={image}
                class="absolute inset-0 h-full w-full bg-background-hihglighted object-cover"
                widths={[400, 900]}
                width={900}
                sizes="(max-width: 900px) 400px, 900px"
                alt={post.title}
                aspectRatio="16:9"
                loading="lazy"
                decoding="async"
              />
            )}
          </div>
        </a>
      ) : (
        <div class="relative h-0 overflow-hidden bg-background-hihglighted pb-[56.25%] md:h-72 md:pb-[75%] lg:pb-[56.25%]">
          {image && (
            <Image
              src={image}
              class="absolute inset-0 h-full w-full bg-background-hihglighted object-cover"
              widths={[400, 900]}
              width={900}
              sizes="(max-width: 900px) 400px, 900px"
              alt={post.title}
              aspectRatio="16:9"
              loading="lazy"
              decoding="async"
            />
          )}
        </div>
      ))
  }
  <div class="mt-2">
    <header>
      <div class="mb-1">
        <span class="text-sm text-foreground-hihglighted">
          <Icon name="ph:calendar-blank" class="-mt-0.5 inline-block h-3.5 w-3.5" />
          <time datetime={String(post.publishDate)} class="inline-block">{getFormattedDate(post.publishDate)}</time>
          {
            post.author && (
              <>
                {' '}
                · <Icon name="ph:user" class="-mt-0.5 inline-block h-3.5 w-3.5" />
                <span>{post.author.replaceAll('-', ' ')}</span>
              </>
            )
          }
          {
            post.category && (
              <>
                {' '}
                ·{' '}
                <a class="hover:underline" href={getPermalink(post.category.slug, 'category')}>
                  {post.category.title}
                </a>
              </>
            )
          }
        </span>
      </div>
      <h3 class="mb-2 font-heading text-xl font-bold leading-tight sm:text-2xl">
        {
          link ? (
            <a class="inline-block transition duration-200 ease-in hover:text-primary" href={link}>
              {post.title}
            </a>
          ) : (
            post.title
          )
        }
      </h3>
    </header>

    {
      post.metadata?.description ? (
        <p class="flex-grow text-lg text-foreground-hihglighted">{post.metadata?.description}</p>
      ) : (
        post.excerpt && <p class="flex-grow text-lg text-foreground-hihglighted">{post.excerpt}</p>
      )
    }
    {
      post.tags && Array.isArray(post.tags) ? (
        <footer class="mt-5">
          <PostTags tags={post.tags} />
        </footer>
      ) : (
        <Fragment />
      )
    }
  </div>
</article>

Blogging in Astro

WordPress is know for its blogging capabilities. Having a good blogging environment is a must for me. So, how does Astro handle it? Well, Astro has a built-in support for markdown files, which means that you can easily write your blog posts in markdown and then have them rendered as HTML. It’s simple, clean, and easy to read. If you need more juice in your blog posts, Astro comes with built-in support for MDX, too. This means that sometime in the future, I can easily add some React/Vue/Svelte components to my blog posts if I need to.

When it comes to styling, Astro can integrate with Tailwind CSS, which is a utility-first CSS framework that many devs love. By using Tailwind’s Typography plugin (and the prose class), you can easily style your blog posts to look nice and clean.

Writing posts without anyone reading them is not fun, so I have to have some way to optimize my SEO. Astro offers several integrations for SEO, like Astro SEO. However, I picked @astrolib/seo, as seems to be more popular one. Both of these integrations give you a component to which you can pass your metadata as props.

One extra thing that I like about Astro integrations for RSS feeds and sitemaps. Having an RSS feed is a nice touch, as it allows your readers to subscribe to your blog. Sitemaps are also important, as they help search engines to crawl your website more efficiently. Both of these integrations are easy to set up and use, so you don’t have to worry about them too much.

Conclusion

When it comes to Astro, I can’t explain how happy I am that I found it. WordPress was a good start, but Astro is the thing that takes this site to the next level. Easy to deploy and maintain, blazing fast, fully customizable, and SEO optimized - what more could I ask for? You can start with Astro by following their official documentation, which is very well written and easy to follow.

If you would like to start with some boilerplate, I can recommend AstroWind. This is a boilerplate that I used to start this website after I got used to Astro (with some of my own modifications). It has everything you need to start your website, including a blog, categories, tags, Tailwind, SEO, RSS, and sitemap integrations.

I hope that you will give Astro a try and that you will fall in love with it as I did. If you have any questions or need help with Astro, feel free to reach out to me on LinkedIn. I will be happy to help you out. Happy coding! 🚀

Related Posts

Read more notes