Angular dev did a blog in Astro
Hey! 👋
First of all: welcome to my blog 🎉
It’s a pleasure to share my knowledge, probably some jokes, tips & overall experience with you!
Disclaimer
Your overall thoughts on Astro can be different - this posts presents my own opinion 😇
Why exactly this topic?
Yeah.. I know it’s the most common topic & it seems trivial, but I HAD TO!
One, really solid Angular player I really like and who (I assume 🤫) likes me a bit, suggested to go with exactly this topic for the first post.
Thank you, your idea was just great! Huge shout out to Mihai Paraschivescu 💛
That&##39;s awesome! Maybe the first post of your blog would be about the experience of building it 🙂 I&##39;d really interested in reading something like that.
— Mihai Paraschivescu (@mikeandtherest) March 6, 2023
How it started? 🛫
I must admit I was really impressed of Astro when I started contributing to (btw. really great) initiative - Angular Snippets by Santosh Yadav
A few things I paid attention to:
- Lightweight
- Simplicity
- Imo great docs
- A lot of integrations
So I thought, yeah… let’s do it
Of course the first step was to install it, boom:
pnpm create astro@latest
Then I was asked about a template: yes, the blog one please...
I looked around 👀
Because as an Angular Dev I was really interested in:
- How routing works
- How to compose components
- How to pass props to components
- Other things…
Routing
The same game as with the Nuxt
- cool
Maybe we’re getting old… 👴
The fresh approaches everywhere… 🍓
It means routes are automatically generated based on folders’ structure
For me it was really beneficial, why?
✅ I love to keep a structure meaningful
✅ This project must be simple
✅ No ...RoutingModule
, const routes = [...]
etc.
Example ⌛️ (time, heh)
- It scans
pages
folder to build the structure - There’s no nesting, so the first
index.astro
is just/
blog
folder means now we have/blog
index.astro
inside theblog
folder represents a structure of/blog
[...slug]
represents a concrete post, so now we have/blog/my-concrete-post
Components’ composition
Pretty cool! We can just…
…use it like in Angular
How to pass props
Let’s assume our HeaderLink
takes position
from the parent Header
<HeaderLink href="/" position={'top'}>Home</HeaderLink>
Then in our HeaderLink
we just:
const { position } = Astro.props;
Integrations ⚙️
This is the part I really appreciate 🤝
How do you think - what else do I need for the blog?
Some styling 🔊: yes, welcome Tailwind!
Some content 🔊: yes, welcome MDX!
Started with simple astro-cli commands:
pnpm astro add mdx
pnpm astro add tailwind
And ended with an Astro’s warm welcome, with everything configured
export default defineConfig({
site: "https://blog.angulion.dev",
integrations: [mdx(), sitemap(), tailwind()],
});
I was also curious how the MDX fetching works. First thing - src/content
is reserved for collections, second thing - these collections are accessible via astro:content
. Let’s say we have a PostLayout
component being a styled wrapper, then we have a [...slug].astro
component loaded basing on nested structure + a slug of a post. The component uses getCollection()
to get the whole collection, then it’s being filtered to find the exact post by a slug
props.
And finally:
const post = Astro.props;
const { Content } = await post.render();
---
<PostLayout {...post}>
<Content />
</PostLayout>
BTW the What you can expect
header and the whole table are automatically generated by rehype-toc
& rehype-autolink-headers
. Tbh it required to be styled, nothing more 😛
Let’s build ⚒️
The biggest benefit of this project was that I wanted go ##YOLO 🤪
Fu** architecture, engineering, thinking about abstractions - it was supposed to be fun, so it was 😀
Landing on the first shot 🛬
Eyoooo beautiful developers 💛
— Bartosz WasiLew 🦁 (@bartosz_wasilew) March 8, 2023
I did whole landing page (from mobile to desktop) for my ##angular blog 🥳
I was brave enough to not to use any „visual template” and play with ##tailwind 💪🏻
What do you think ? 🤔
👇👇👇 pic.twitter.com/bZ0WaIYUNc
By doing a landing I did some new Astro components, really nice & smooth
Browse all posts page 🔎
Here I just reused some components from the previous page - 😎
However, title of this page contains “Browse”, so I thought it’d be nice to have some search bar
astro components === non-client code
💡 It means we’ve no access to window
or document
Vue components to the rescue 🤝
Are u still here? So here we go again:
pnpm astro add vue
And we’re home, keeping in mind one quote from the greatest monk ever:
Vue components in Astro, no Astro components in Vue
EASY 🔥
Blog post page 🗾
For the first time it seemed like everything works
Markdown doesn’t work properly for headers, lists, etc.
I still don’t know what’s wrong 🤪, but workaround was to use global
styles assuming the only article is the blog post one
EASY 🔥
I also had a problem with non-working tailwind (vue)
This time I was just stupid, apologies
You didn&##39;t add vue to {astro, html}?
— Coby (@Blue_Boy_x)
March 14, 2023
SEO 🧑💻
Yeah.. again - I was warmly welcomed by the built-in BaseHead
component:
<!-- Global Metadata -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<!-- Canonical URL -->
<link rel="canonical" href={canonicalURL} />
<!-- Primary Meta Tags -->
<title>{title}</title>
<meta name="title" content={title} />
<meta name="description" content={description} />
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content={Astro.url} />
<meta property="og:title" content={title} />
...
...
Then, as we already know the flexibility of Astro, it can just be used in other components
<!DOCTYPE html>
<html lang="en">
<head>
<BaseHead title={SITE_TITLE} description={SITE_DESCRIPTION} />
</head>
Small adjustments and we’re home again!
Deployment
Oh c'mon maaan, that's TOO EASY!
I used Netlify, so:
- Click to connect repo
- Build command + dist
- Click
- Done
And in the meantime setting a domain with SSL
BTW. I don’t use SSR!
What’s more, astro-sitemap
plugin takes care of creating a sitemap ‼ NICE
A11Y, Performance, Best practices
Let’s begin with the Lighthouse report 😀
At this point I just adjusted semantics, because of semi-#YOLO building
A11y
Unforunately, I haven’t found any good #accessibility tricks in the blog template, maybe I selected wrong one. Anyways - proper sectioning, aria-labels, alting… even skip to content did a trick!
Performance & Best practices
I had one problem with content compression - no problem, there’s always astro-compress
easy to integrate as other tools. COOOOOL!
btw.. when you’ll see 272 console issues
- that’s the problem of embedded tweets & twitter itself
Wrapping up 🔥
I really enjoyed working on this project
For me Astro was the best choice:
- Wider perspective / get out of (Angular) comfort zone
- Simplicity
- Easy integrations
- A lot of built-in components/approaches
- Hugely customizable
- Good docs
- And the most important: it was a fun to work with it
Keeping in mind simplicity, no complex logic, no advanced data manipulation, no need to make it hugely scalable - that’s why I didn’t choose Angular (which I love btw)
- - Yours truly