If you don't know how to properly manage things like SEO, content structure, and relationships between content inside Astro, or you're coming from somewhere like WordPress, Webflow, or Sanity, this is going to fix that. So in this video, I'm going to show you how to set up your content model for your SEO fields, your URL structure, and your Astro content collections, and you won't have to rely on traditional CMSs.
Instead of clicking through 10 different admin panels, like in WordPress, for post types, custom fields, SEO settings, and permalinks, we're going to define the entire system in one place using a chat interface and AI-assisted coding. So by the end of this, you'll have a clean, scalable way to manage your content faster, simpler, and way more consistently.
Here's exactly what we're building in this video. We're creating three content collections: posts, glossary terms, and authors. Posts are your main content, like blog posts. Glossary terms are definition pages that support internal linking and programmatic SEO. They also act as archive-style pages. Authors gives us a single place to manage the author data instead of repeating it across every post with plain text.
Then we're defining the frontmatter for each of these, which replaces things like custom fields and ACF and SEO plugins. That includes titles, excerpts, SEO metadata, featured images, and URL control using slugs and permalinks. Finally, we're connecting everything together using Astro's reference system. So instead of loose tags or duplicated data, we have real relationships between the content.
By the end of this, you'll have a structured system for managing content, SEO, and site organization without needing a CMS at all. Here's the actual prompt that we're going to be using during this part of the process, and let's go through it together. I'll explain exactly why we have each of the things in here.
You're working inside of an Astro project that uses content collections. This project has three MDX content collections. The MDX is used instead of the MD files in order to allow you to add components inside of the MDX body. So if you want to add some kind of callout or something, our three different collections are posts, glossary, and authors.
Posts are going to be like your basic blog posts. Again, the glossary is the terms, and then authors is just whoever wrote it. Eventually, if I have guest post authors, then we can add those, but if not, then I'll just add myself as an author. That way, it's clean and consistent, and I can just post an avatar photo once.
We're going to define and standardize the frontmatter schema. This is, again, the replacement for something like custom fields inside of ACF or Meta Box for each collection. Then we're going to correctly implement relationships between them using Astro's content collection reference systems.
Another part of the strict constraints that we're putting up here is do not build layouts, do not build components, do not implement rendering logic, and do not generate full content systems. We're doing this one step at a time, and typically when you one-shot it or give the entire project inside of a single prompt, then it is too much context and it makes a lot of mistakes.
Here's important project context. We have electrician websites, SEO for electricians, and electrician marketing. Basically, these are my three different categories or content silos. Eventually, the idea is that if you have this as your category, and then each post becomes another name inside of that inside of the URL, then you can eventually rank for, say, electrician websites by itself. You build this as a page by itself, and then eventually, since it's such a broad keyword, hopefully you can rank for that. That's the strategy that we're using here. You can follow along with me or choose your own niche.
Down here, we have the glossary pages. Each glossary page acts as a definition page and the archive page for related posts. There should be no separate tag archive system. The reason that we're doing this is that we don't want a tag system living alongside the glossary system. Basically, when we have a glossary term like SEO, that will be a tag per se. We don't want duplication, number one.
Number two, we're going to have it built into the Astro content references. Here's the relationship model. We have posts related to the glossary. Posts reference glossary entries. Each post should include glossary terms. This is going to be a field inside of the frontmatter. The field must be an array. That means we can have multiple glossary terms for each post.
If I have a post about electrician websites and then I talk about SEO and web design, then it could reference two different glossary terms: the SEO glossary term and the web design glossary term. That means we have multiple items in an array, and these reference entries in the glossary collection. That's one of the content collections that we have. We're using this instead of just a frontmatter tag that could be used for filtering, in order to create a better relationship.
This creates a many-to-many relationship. One post can reference many glossary terms, and many glossary terms can reference many posts because there's going to be many posts about SEO, many posts about web design, et cetera. Then we have our post to authors. This is pretty obvious. Each post is going to have an author.
Now here we get into the posts schema. Each field here is part of the frontmatter. In Astro, we have the relationships between the content collections or the post types, between posts and the glossary terms and authors. Inside of Astro, instead of just creating a filterable frontmatter schema, we can use their built-in collection references.
Our reference means that this field is not just plain text. It points to a real entry in another content collection. In our case, glossary terms points to entries in the glossary collection, and author points to an entry in the author collection. This matters because it gives us real relationships instead of those loose labels.
A post can reference multiple glossary terms, which gives us the many-to-many relationship. A post can reference one author, which gives us a one-to-many relationship. Astro validates these references, and then later we can fetch those related entries directly. Instead of guessing with strings inside of the frontmatter, we're connecting content to real content that Astro understands and is verifiable.
If you go to their help docs here, I'll leave the link down below, you can see exactly how they describe it. Collection entries also reference other related entries. With a reference function, you can define a property in a collection schema as an entry from another collection.
Here's probably the easiest way to understand it. For example, you can require that every space shuttle entry includes a pilot property, which uses the pilot collection's own schema for type checking, autocomplete, and validation. This kind of makes sense. You have a space shuttle and each space shuttle has a pilot. You have a recipe and each recipe has ingredients. So you end up making some kind of relationship. That's the idea here.
A common example is a blog post that references reusable author profiles. That's what we're doing. That's one of the things we're doing. If you want to get into the code or go ahead and look at it a little more deeply, you can go ahead and check out this page.
Let's continue explaining the prompt itself. Right here is the content collection posts and its schema, or its custom fields if you're used to that. Here are the required fields that we have. We have the title, the excerpt, the author, which is a reference to me, my author content collection entry, the published date, and the silo or the category that it's going to use for each one, which will be inside of the URL.
Then the glossary terms, which is an array of references. Again, you can have multiple glossary terms attached to each post. Then we have the featured image and its alt text. Then we have optional fields, which is the updated date, so you can handle that however you want. If you want to just change the published date with your workflow, if that's how you do it, you can do that.
You can update the canonical URL and the OG image. If you're going to share your post on social media, if you have a workflow that uses drafts, we have that there. Then there's noIndex. If you don't want this to be indexable, you can go ahead and set that there.
If you have an SEO title or a meta title that you want, or an SEO description or meta description that you prefer for SEO purposes, you can go ahead and have that different and written here instead of the regular title and excerpt above. Those two are related by a fallback rule, which we'll see below.
Next up is the glossary content collection schema. We just have the term, its definition, so the basic definition part, and then we have why it matters. Instead of having just a very bland, blank page that just says a definition, we also have why it matters for this niche. My niche is electricians. Basically, I just say, why does SEO matter for electricians? Why do you care about it? I'll probably get more in-depth with it later as I build out the layout, but for right now, that's what I have.
We have the featured image and its alt text. I do not need an author field for the glossary term. It's not a work of art. Then we have our authors content collection. I'm keeping this simple purposefully right now because I don't have guest posts and all that. So just the name, the slug, avatar, and the text for that image. I just gave it myself as an initial author entry, so it has something to put into the website.
Then we have some critical rules. We don't want any duplicate fields. For example, we don't want SEO title and meta title. We don't want some kind of confusion by creating fields that are going to be used for the exact same thing. That will confuse us and the LLM.
Here's the SEO fallback logic I was telling you about. If you don't have an SEO title or you don't use that in your workflow, then it would just fall back to the title. SEO description falls back to the excerpt, and the OG image falls back to the featured image if you don't define an OG image or change it. Of course, the canonical URL is taken care of by Astro unless you change it there.
Down here we have non-computed fields. I was thinking about adding read time, breadcrumbs, and that type of thing. There are different plugins and methods for taking care of that, which we will use in the future, but this is basically just to keep this setup minimal at the moment.
The slug handling: you don't want to use the word slug inside of your frontmatter because then it's going to interfere with Astro's system, and that could break things. We're just making sure it doesn't do that. If we want to change the permalink for each individual post, we can do that later.
Here's an important one: image handling. You don't really define image handling, say in the frontmatter itself, because Astro has its own special system for handling images where it converts things to WebP and resizes them and all that kind of fun stuff. That is handled when you go ahead and create a component. That's at the component level, or you can define it inside of the MDX body itself too. That'll be handled there, so we don't need to worry about that as we make the content collections.
Then here's just the set of tasks for the LLM to go ahead and do. It's going to update or create the content collections config, define the posts, glossary, and authors schema, and then it'll implement the glossary terms references and the author references that we described. Then, of course, my one author entry. It will enforce the categories, the content silos, and then we're just telling it to keep everything minimal.
The output: we're going to tell it to output something so we can validate what it actually did. The first thing is to update the content collection config, and then we want an explanation. It usually does that by itself anyway. For the sample posts MDX file, we want that so we can actually go ahead to the front end and see all these things that we set up, to see if it's actually working and actually taking hold. It's going to show us if everything is connected.
Then we have the sample glossary MDX file so we can see how that looks and make sure that's working properly. Of course, we have the sample author MDX file, which we already gave it an entry for. Another big one for SEO is the URL explanation, so we can see how it constructed the URLs and if it's working the way we want for SEO purposes.
After that, we just have a couple final restrictions for it, and that is the prompt. You can go ahead and alter it and change it for whatever fits your use and your niche. Hopefully that's helpful. Now that we have the prompt all set up and altered to our liking, what we're going to do is go ahead and paste it into VS Code and let it go to work.
Inside of VS Code, make sure that your project is open. Then you can paste in your prompt. If you want, you can go ahead and change the model or the thinking level. I'm going to go to GPT-5.4 and we'll give it extra high thinking. Again, if you use a higher level of reasoning, then it's going to take longer. I'm going to go ahead and send it and see what happens.
It has finished. Let's go ahead and see what the output is. It worked for 5 minutes and 47 seconds. It standardized the collections in the config.ts and added the initial author entry. It updated existing sample content to match the new schema, and they checked it out.
Here's the updated content collection config. Here's the explanation. Post author now uses reference authors. Excellent. Post glossary terms now uses the array. Post.silo is strictly limited to our three categories, so now if we try to do something else, it's going to validate it and say, hey, you can't do that. Glossary is minimal. Authors is minimal, and we have our SEO fallbacks in place.
We have our sample posts there, and here's the URL explanation, the silo, and the slug. That looks like exactly what we wanted. Next steps says, if you want, I can do a second pass to add getEntry and getEntries helpers for resolving author and glossary references cleanly at query time, and I can also normalize the remaining sample post and glossary bodies so the seed content reads less like scaffolding.
I'll go ahead and do what it recommends. After that, we will take a look at the sample MDX files. We'll go ahead and say complete the next steps and see how that goes. That portion is finished and it took 2 minutes and 47 seconds.
What changed? It added relation helpers in the content.ts for authors, glossary terms, and post relations, and it replaced scaffold copy with realistic seed content. That way when we look at the MDX files, it's going to look like better placeholder content. That's important for us when we go ahead and take a look on the front end.
It gave us some extra next steps. It says, wire these helpers into the glossary term page so each glossary entry can render its related post archive, and wire the getPostRelations into post pages. Basically, it wants us to wire up the relationships a little bit better so it can do query loops.
Typically what I do is I read over the next steps after each run, and then if it makes sense, I go ahead and do it. Let's go ahead and tell it to do these next steps. I say, you can go ahead and do the next steps. Then we'll see what that outputs.
It worked for another 1 minute and 42 seconds and it implemented post pages that now resolve relationship data through the post relations, and the glossary terms render a derived related post section. The next steps say to preview the affected pages in the browser. It looks like essentially we're done.
The next thing we want to do is ask it to set up a locally running server and then ask for the URLs. I said, start a local server and give me the URLs for all the sample MDX pages we made. It worked for 27 seconds, and now we have some URLs to go ahead and take a look at.
This is the content silo electrician websites, and the sample post is electrician website pages that convert. This is what it would look like. They made an author section right here with a published date, and here are the glossary terms. I click on that, then I have the glossary page itself. If you look at the URL here, it has glossary slash A slash analytics. That's basically exactly what we're looking for in terms of URL structure.
Again, we're not making the page layouts and designing the page itself right now. We're just coming up with a structure. Let's look at another one. This one says this is for local SEO. This one has backlinks: links from other websites that point to your website and signal credibility.
This is all looking pretty good. We have validated that the posts themselves work and that the glossary terms are working. Let's have a look at the author page. We don't have anything for the author page yet, so that means we haven't created a layout for the author page yet, which is completely fine. I'm not sure if I actually want it on the site or not because we have an about page for that, but we don't want a broken link later, so we'll have to double check that.
What we're going to do is take a look at this posts MDX file inside of VS Code. This one is called 7 pages every electrician website needs to turn visits into calls. If we go under src, and then under content, under posts, because there's a posts collection, and then go to electrician website basics, we can see that the title is here. Let's see if that matches up. Here's the title.
How about the silo? Here's the silo. That matches up here. How about the slug? Electrician website pages that convert. If we go up here into the slug, that's what we have there. Those are all matching up, and we also have the publish date. As you can see, when you edit something here in the MDX, it'll update over here too.
How about we change the date to the 22nd? We'll change that, click save, and we can see that the published date has changed. Everything is connected up and working nicely. Here is the content itself.
As you can see, the MDX file for the posts collection is connected up and working well. Just to recap what we actually did here today, we built out the full content schema and frontmatter structure for our content collections, including the posts, glossary terms, and authors.
We set up the foundation to properly manage SEO across the whole site without relying on plugins or a traditional CMS. More importantly, we created real relationships between the posts and glossary terms using Astro's collection references. That gives us a true internal taxonomy system, clean interlinking, better UX with archive-style glossary pages, and a strong foundation for topical authority and programmatic SEO.
We did all that without going into the backend of a CMS and manually creating custom post types, custom fields, and other settings one by one. Instead, we sat down, thought through our SEO strategy and content structure, and turned that into a clear, organized prompt that an LLM could understand and execute.
Instead of spending hours clicking through the admin panels, we spent that time designing the system once and letting the code generate from the prompt. If you want to use the exact prompt from this video as a starting point, you can go to thomasfellows.com and copy it with one click, and then you can adapt it to your own project.
Honestly, what I'd recommend you do is paste that prompt into something like ChatGPT and just have a conversation with it so you can refine it based on your own specific project needs and then use it. That's going to get you much better results.
If this video helped you understand how to structure content and SEO properly in Astro without a CMS, make sure to subscribe. In the next video, what I'm going to do is take this system and start building an actual post layout. We're locking the fonts, typography styling, and overall design system. We'll also start creating reusable components for the post content collection. By the end of that, you'll have a consistent design system across your entire site.