Boost Your Next.js and Astro Projects: Effortless OpenGraph Image Automation
PixelPalooza will explore all the ways we, as developers, can leverage media like images, video, audio and documents across our sites and applications.
We all know that great content is key, and Astro is one of the best frameworks for building fast, SEO-optimized, content-first websites. But what if you could take it a step further?
In this talk, I’ll show you how to harness Astro’s Content Layer to create a custom loader that can pull data from virtually any source. I’ll be using Strapi, a powerful headless CMS that makes it easy for content managers and editors to handle and update their content effortlessly.
Join me to explore how you can bring content from anywhere and make your content flexible, and easier to manage!
Developer Advocate at Strapi by day and content creator by night, Paul Bratslavsky, loves learning new things and sharing them with others. He is a big fan of everything Javascript.
Paul Bratslavsky 0:19 Thank you CodeWord for having me. I’m excited to be here and excited to give you this presentation today. My name is Paul, and I work as a developer advocate at Strapi, and today I’m going to talk about bringing your content from anywhere with Astro content layer loaders. And today, we’re going to take a look how we load data in Astra today, Markdown is awesome, but and why I headless CMS. And more importantly, the most important part of the talk, we’re going to talk about custom Astro loaders because they are awesome, and we’re going to use this basic website as context for our demonstration. So let’s start by the first way that we are able to fetch data in Astro and we’re going to take a look how I’m fetching data for this top navigation here. And I’m literally doing the most simplest thing possible, which is hard coding the data in Astro’s front matter, then iterating through it to display the top navigation on my website. As you could see, I do have some more code here, but for our purposes, this is all we need to think about. We have front matter. We are hard coding our data, and we are iterating through that data and rendering it to our screen, showing our amazing top navigation. We can also, instead of hard coding our data, make a request to an API, get the items and iterate through those items and render them to screen. Another way that we could load our content in Astro is literally store it as markdown inside our routes, for instance, inside my Pages folder, I created a file called example markdown. This file has my basic block content, and I could navigate to this page directly, and Astro is able to render this page, no problems. So one huge benefit of Astro is that you’re able to store your content inside your project via markdown, which could live on GitHub, which is pretty cool. One issue that we have with this method is that we’re not able to type our content and have it be type checked when our Astro project builds. So in case there’s an error, we want to make sure that we catch it, and this is where content layer API comes in. You could learn more about collection in the documentation, but general idea inside the Content folder, you will be able to create a directory where you could able to store your data. It could either be markdown, MDX, YAML or JSON. Now let’s take a look how I’m representing this blog content in my application. Using the content layer inside my project, I have a folder named content. If you take a look inside, I have a folder called blog, and this is where all of my markdown lives. If you take a look at the Markdown file, you could see that we have title, description and a slug. So now I want to define a collection that is going to reference all these items inside the block folder. Let’s take a look how we could do that. Navigating to our config.ts file, we are able to use the Define collection method to define our block collection that is going to reference our items inside the block directory. Notice that I’m using zad for basic validation, where I’m saying title is a string description and slug. And again, this is very simple validation, but this is going to allow us to get TypeScript on our content. Once I define my collection, I’m able to export it here, and this is going to be called blog. And now let’s navigate to our index page in our blog folder. And you could see here that I’m using get collection method. I’m referencing the collection by name, called blog, and if I hover over markdown post, nor is that be getting our types. Now that we have the basics around content collections and how we are able to organize our content and use that validation to add type safety. Let’s quickly revisit our markdown content taking a look in the code. Our content is stored inside our code base, so there is no easy way for a non technical user to update this content. Second, if we take a look at our markdown content. Markdown is amazing, but maybe we want to have more flexibility of how we organize this content, and this is where something like a headless CMS could come in. So now let’s go over a quick benefit of why using a headless CMS to manage your content with Astro might make sense if we take a look at the blog post. Post and take a look at our items. Here, we could see that we have different sections. We have our text, we have a quote, we have an image, we have more text, and we have this little basic slider. If we take a look in our shapi application, under our content manager, take a look at the articles. We have this admin area that allows non technical users to be able to manage their content. So you could see that the content that we have represented in our Astra app is represented by a structure here, so our rich text is responsible for our markdown, we have our quote block, we have our media, we have our rich text, and we have our slider. And through this concept of blocks, you’re able to organize your content in a way that makes sense to your team. So you could have a non technical editor who’s able to go inside your application and make all the necessary changes. So the beauty of combining Strapi, headless CMS with Astro is that allows you to be more flexible with your content. So if you have a lot of content, and you have non technical users that have to manage the process, have Take care of your content and allow your non technical users to make changes and push the changes to your Astro application, I think it’s a match made in heaven. And to make this even easier, Astro has given us the power to create custom loaders that you can use to point not just to your headless CMS that you’re using, but to any place on web or API where you need to load data. So let’s take a quick look how I accomplish this in my project. So back inside our config.ts file, you could see that I have a collection name called Strapi post loader. And if you take a look, I’m using that same method define collection, and I’m defining a loader and pointing to a custom Strapi loader that I created, then I’m exporting it in the same way. And if we take a look under our pages inside our Strapi block, index dot Astra file and scroll to the top, notice that when I hover over Strapi post, you could see that we’re getting all of our types that our content structure expects with this type safety, not only does it improve our development experience, because we could easily tell all the items that our data contains, but also during build time, it will catch any errors that we may encounter. So now let’s take a look at our loader in more detail. Azure has the loader method that allows us to create custom loaders. If we take a look at the code here, I’m defining a function called Strapi loader, which is going to be responsible for fetching our data. The three things that it expects is a name our load function with a custom code and a schema. You could make this as simple as you like, where you just fetch the data, and you could manually define your schema. I’m going to make sure to link to the code base in the notes so you can take a look, and this is my first version of the Strapi loader. But if you take a look, I am fetching the data from Strapi and then I have a schema that I’m referencing to type my response, and if we scroll back to schema, in this particular case, instead of manually defining my items, what I’m doing is I’m fetching the Strapi schema that represents the structure of my data, and I have a function called generates that schema, which uses The map type to Zod schema, which will iterate through our Strapi schema, and based on this, generate dynamically the Zod schema that’s required to type our content. What this allows us to do is to get this dynamic typing to our API response that we get, which is pretty cool, but it’s up to you, how you structure your custom motor, the basic elements and greetings that you need. It’s the name a load function and a schema function that could either be generated dynamically or you could specify ViaSat yourself. Then you create a collection type that’s using your custom loader. And the way we created this loader, where you point to any collection type that you have, it will automatically fetch your data. Then you export your loader, and then you’re able to use it in your code base, just like I’m doing here inside our index dot Astra page, where I’m getting Strapi post data and I’m rendering inside my Astra project, which takes all of our data stored in Strapi and renders all these sections on our front end. And before I go, I want to show you how I am rendering the dynamic data from Strapi. Here in my components, I have my blocks. For instance, you could see media, quote, richtext and slider. These are the same blocks I have in Strapi media, quote, rich text and slider. And inside my Astro application, I create a component called Block renderer. If we take a look at the code, it loads in all my custom Astro components representing each block. I iterate through the data and then I render it to my. Screen, and this is how we’re able to get our dynamic page from Strapi inside our Astra application.
I hope you enjoyed this talk as much as I loved giving it. And the most important part I am working on the custom loader from Strapi. But it doesn’t have to be Strapi. You could build the custom loader for any endpoint or other CMS or even WordPress that you need. And this is the beauty of Astro, is that it gives you that flexibility to build and easily load data from any source that you want. You’re no longer bound to having to have your data live in your Astro GitHub repo. But instead, could define collections that call external APIs that give you the best of both worlds. You could have the power of Astro and custom loaders and collections, but you could also have your headless CMS that makes it easier for non technical users to manage the data, regardless if you have 10 pieces of content or 1000 pieces of content. But with that being said, thank you so much for checking out my talk. And you could check me out on Twitter at coding 30 and ask any questions that you like. And if you have any questions about what I’ve done here again, I’ll leave the repo in the notes. Feel free to reach out to me, and I’d love to answer any questions that you may have see you in the next one. You.
PixelPalooza will explore all the ways we, as developers, can leverage media like images, video, audio and documents across our sites and applications.
Content is rarely a topic developers focus on, even though it is a critical aspect to what they build. CodeWord Conf is all about the combination of code and content.
Content is rarely a topic developers focus on, even though it is a critical aspect to what they build. CodeWord Conf is all about the combination of code and content.
Eric Carlisle the benefits of Astro's islands architecture and support with other popular framework components.
TheJam.dev is a 2-day virtual conference focused on building modern web applications using full stack JavaScript, static site generators, serverless and more.