This page looks best with JavaScript enabled

Create a Blog with Astro

 ·  ☕ 5 min read

With Astro 4 released recently, I wanted to check out what is going on in that part of the world. What better way to do that than to create a blog using Astro.. or so I thought.

I had not been quite sold on Astro for the stuff that I typically do.

  • I tend to focus more on SPA-like apps. Am a fan of Vue, of course
  • Hugo is more than enough as SSG. While I absolutely have no clue what I do there 90% of the time (or is it more like 99%?), it just works and works blazingly fast

Being a stickler to “try everything that is recommended on Twitter”, I could not continue the state of not jumpin on the Astro train for long. So, here we are.

What is Astro?

The official astro.build website says:

The web framework for content-driven websites.

The categories listed out there include -

  • Marketing & other content sites
  • Blogs
  • eCommerce
  • Portfolios
  • Documentation (not featured, I see this as a good thing)

Astro is not the typical SPA, MPA or SSG.

You use Astro to -

  • Build your app in components and connect all of them
  • Deliver pages to client with no or minimal JS
  • Use your favorite framework (React, Vue, Svelte, Preact, etc) for SSR or for interactivity

In terms of how all of that comes together -

  • Astro creates static pages for static or dynamic routes
  • Astro components and pages, as well as any of the components of the frameworks you use, are compiled to static pages. Addition of different frameworks in different pages or even on the same page does not necessarily mean performance impact .. if everything is server rendered
  • Client interactivity can be with any framework of your choice, or with JS
  • Get content from Markdown etc. or from external sites
  • Astro provides many features (e.g. vue transitions, routing, image optimization, etc.) out of the box

Focus on developer experience and content sites means there are ** a lot of ** amazing features -

The below image on performance speaks volumes.

astro performance

Create a blog using Astro

Let us get back on the topic at hand.

Create a blog by issuing the below command -

1
pnpm create astro@latest

Select the right options thereon. I chose the blog template with some dummy content for demo purposes.

astro create

Run the app -

1
pnpm dev

And, voila..

astro-blog-template-home

If I was honest, there is nothing more to say. But, I will continue blabbering on since creation of a blog with just one command is just crazy.

What have we created so far?

The structure of the application is inline with the expectations of a typical JS app -

  1. public directory with all static content
  2. src directory with all the code
  3. src/page directory with all pages. You will see a curios markdown like header in the page that includes Javascript code. This is the frontmatter that is used to import components, data, etc. into the page. For e.g., see pages/index.astro -
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    ---
    import BaseHead from '../components/BaseHead.astro';
    import Header from '../components/Header.astro';
    import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
    ---
    
    <!doctype html>
    <html lang="en">
        <head>
            <BaseHead title={SITE_TITLE} description={SITE_DESCRIPTION} />
        </head>
        <body>
            <Header title={SITE_TITLE} />
            <main>
                <h1>🧑‍🚀 Hello, Astronaut!</h1>
                <p>
                    Welcome to the official <a href="https://astro.build/">Astro</a> blog starter template. This
                    template serves as a lightweight, minimally-styled starting point for anyone looking to
                    build a personal website, blog, or portfolio with Astro.
                </p>
                <!-- snip -->
            </main>
        </body>
    </html>
    
  4. Components that are imported in pages (or within other components) in src/components
  5. src/layouts and src/styles directories that supplement pages & components
  6. src/content directory with all content. Static content is seamlessly integrated into the app. For e.g., see pages/blog/index.astro -
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    ---
    import Footer from '../../components/Footer.astro';
    import { SITE_TITLE, SITE_DESCRIPTION } from '../../consts';
    import { getCollection } from 'astro:content';
    
    const posts = (await getCollection('blog')).sort(
        (a, b) => a.data.pubDate.valueOf() - b.data.pubDate.valueOf()
    );
    ---
    <!-- lot of lines -->
    posts.map((post) => (
                        <li>
                            <a href={`/blog/${post.slug}/`}>
                                <img width={720} height={360} src={post.data.heroImage} alt="" />
                                <h4 class="title">{post.data.title}</h4>
                                <p class="date">
                                    <FormattedDate date={post.data.pubDate} />
                                </p>
                            </a>
                        </li>
                        ))
    <!-- more lines -->
    
  7. Seamless styling scoped to the components or applied globally

Gotta say, I love the -
- 📄simplicity
- 🧩component architecture that just focuses on what is needed - no fluff

Remember all of this came with the template, I have not done anything yet.

Level-up the blog

Add a sitemap

Add a sitemap with a plugin. A single line configuration should be good in most cases-

1
2
3
4
5
6
7
// astro.config.mjs
export default defineConfig({
  // ...
  site: 'https://awesomesite.club',
  integrations: [sitemap()],
});
// ...

Embed videos, tweets, etc. in the blog

Use one of the many plugins (e.g., astro-embed) -

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
---
# src/content/examples/page.mdx
title: My MDX page with embed components
---

import { Tweet, Vimeo, YouTube } from 'astro-embed';

Embed a tweet _in Markdown_!

<Tweet id="https://twitter.com/astrodotbuild" />

<YouTube id="https://youtu.be/gxBkghlglTg" /

Make SEO better

Use a plugin like astro-seo and some code to level-up your SEO game.

Add Comments

Add Disqus or Utterances to add comments to your blog.

Add Analytics

Add Google Analytics or Vercel Analytics to add analytics to your blog.

Leverage Partytown plugin to lazy load everything.

Conclusion

Astro is just spectacular and consider me intrigued.

I am half-tempted to switch my blog to Astro - am sure that will take me down yet another rabit hole.

Stay in touch!
Share on

Prashanth Krishnamurthy
WRITTEN BY
Prashanth Krishnamurthy
Technologist | Creator of Things