Skip to content

Commit 7acaeb3

Browse files
committed
feat: add new blog post
1 parent 9e54c11 commit 7acaeb3

File tree

2 files changed

+137
-13
lines changed

2 files changed

+137
-13
lines changed

src/content/posts/why-astro.md

+137-13
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,148 @@ author: "Lucas Machado"
66
tags: ["astro", "blogging", "learning in public"]
77
---
88

9-
# Heading 1
9+
Recently I've been very nostalgic about the internet of my teenage years (around 2010).
1010

11-
This is a paragraph with _italic_ and **bold**, as well as ~strikethrough~ sample text.
11+
I vividly remember having loads of free time and endless, varied interests. I'd get home from school, sit in front of the computer and try to think of a random topic, say, skateboarding. It was amazing just how easily you could find high-quality, user-generated content about your hobbies. People would spend their time writing blog posts on Blogspot, or recording vlogs to upload to YouTube.
1212

13-
## Heading 2
13+
Nowadays, technology has evolved in the direction of SEO optimization and AI-generated articles, so those days are long gone. Thankfully, through the [Wayback Machine](https://web.archive.org/) you can still find those random personal websites where strangers would share their interests with the online world, and, when you do, it feels like you've just stumbled upon a relic of a distant, simpler past.
1414

15-
Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis.
15+
## Astro
1616

17-
## Heading 3
17+
Enter [Astro](https://astro.build/), yet another JavaScript framework. But here's the fun part - it's the best tool for the job when it comes to building content-driven websites in a timely manner.
1818

19-
```js
20-
const ref = React.useRef();
21-
React.useEffect(() => {
22-
ref.current = "some value";
23-
});
19+
This blog post, for instance, is currently being written in a Markdown file. And, as I write it, everytime I hit save on my text editor, I get to see the resulting HTML and CSS being rendered in real-time on my browser window, just as the end-user would see it.
20+
21+
Once I'm done writing, all I need to do is commit the changes and push them to the main branch on GitHub, which has a workflow configured to auto-deploy the result to GitHub pages.
22+
23+
```bash
24+
git add .
25+
git commit -m "feat: add new blog post"
26+
git push
27+
```
28+
29+
It may not sound like much, but for a computer nerd who enjoys writing on his spare-time, like yours truly, this is awesome.
30+
31+
Now, let's pull back the curtains to see how it actually works.
32+
33+
## Build a Blog
34+
35+
The (simplified) project structure looks something like this:
36+
37+
```bash
38+
.
39+
├── astro.config.mjs
40+
├── node_modules/
41+
├── package.json
42+
├── package-lock.json
43+
├── public
44+
│   └── favicon.ico
45+
├── README.md
46+
├── src
47+
│   ├── components
48+
│   │   ├── BlogPost.astro
49+
│   │   ├── Footer.astro
50+
│   │   └── Header.astro
51+
│   ├── content
52+
│   │   ├── config.ts
53+
│   │   └── posts
54+
│   │   └── why-astro.md
55+
│   ├── layouts
56+
│   │   ├── BlogLayout.astro
57+
│   │   └── RootLayout.astro
58+
│   └── pages
59+
│   ├── blog.astro
60+
│   ├── index.astro
61+
│   └── posts
62+
│   └── [...slug].astro
63+
├── tailwind.config.cjs
64+
└── tsconfig.json
65+
```
66+
67+
Let's start with the `./src/content` directory, which is a reserved path for storing and managing content within Astro projects, using a feature called [Content Collections](https://docs.astro.build/en/guides/content-collections/).
68+
69+
At its most simple, it's just a folder called `./src/content/posts/` where all the blog posts are stored. Then, on the `./src/content/config.ts` file, you can define and export your collections.
2470

25-
// then, later in another hook or something
26-
React.useLayoutEffect(() => {
27-
console.log(ref.current); // <-- this logs an old value because this runs first!
71+
```ts
72+
import { z, defineCollection } from "astro:content";
73+
74+
const posts = defineCollection({
75+
type: "content",
76+
// This is literally just a Zod schema
77+
schema: z.object({
78+
title: z.string(),
79+
author: z.string(),
80+
date: z.date(),
81+
tags: z.array(z.string()),
82+
}),
2883
});
84+
85+
export const collections = {
86+
posts,
87+
};
2988
```
89+
90+
Now, let's take a look at the `./src/pages/posts/[...slug].astro` page. Keep in mind that Astro uses file-based routing, so the path above will reflect the actual URL of your blog posts.
91+
92+
```astro
93+
---
94+
import { getCollection } from "astro:content";
95+
import BlogLayout from "../../layouts/BlogLayout.astro";
96+
97+
export async function getStaticPaths() {
98+
const blogPosts = await getCollection("posts");
99+
return blogPosts.map((post) => ({
100+
params: { slug: post.slug },
101+
props: { post },
102+
}));
103+
}
104+
105+
const { post } = Astro.props;
106+
const { Content } = await post.render();
107+
---
108+
109+
<BlogLayout frontmatter={post.data}>
110+
<Content />
111+
</BlogLayout>
112+
```
113+
114+
I just love how simple the code spinnet above is in contrast to what it acomplishes. It's a dynamic route (almost exactly the same as in Next.js) which uses Static Site Generation (SSG) to determine the route path of all the blog posts in our `"posts"` collection at _build_ time.
115+
116+
Then, via props (almost exactly the same as React), you can access the individual blog posts, render the Markdown source file as an Astro component and wrap it in a layout with pre-determined styles.
117+
118+
That's _almost_ it. Now, we've dynamically created a route called `https://my-blog.com/posts/my-post`, but we still need to create a link that will redirect the user to said blog post, or even, any blog post the user may wish to read.
119+
120+
```astro
121+
---
122+
import { getCollection } from "astro:content";
123+
import Layout from "../layouts/Layout.astro";
124+
125+
const postCollection = await getCollection("posts");
126+
---
127+
128+
<Layout>
129+
<h1>
130+
My Blog
131+
</h1>
132+
<p>
133+
Welcome to my blog.
134+
</p>
135+
<ul>
136+
{postCollection.map((post) => ({
137+
<li>
138+
<a href={`/posts/${post.slug}`}>
139+
{post.data.title}
140+
</a>
141+
</li>
142+
})
143+
</ul>
144+
</Layout>
145+
```
146+
147+
Here, we're just awaiting our collection of blog posts and mapping the resulting array into various `<a>` tags.
148+
149+
## Conclusion
150+
151+
Given enough spare time, you can get way more fancy than this, but this is how the most basic blog setup works in Astro.
152+
153+
I highly recommend following their official tutorial called [Build your first Astro blog](https://docs.astro.build/en/tutorial/0-introduction/).

src/pages/newFile.tsx

Whitespace-only changes.

0 commit comments

Comments
 (0)