← All articles

A Maintainable Content Architecture for Astro

How to structure collections, routes, layouts, and translations so an Astro publication remains easy to extend.

THE SHORT VERSION

Keep article data in a typed collection, keep route files thin, and let shared components own presentation without owning content.

A content-focused Astro site can begin with a few Markdown files and one dynamic route. As the publication grows, translations, categories, related content, metadata, and design variants can turn that simple start into scattered conditional logic.

The architecture stays manageable when each layer has one clear responsibility.

Put repeatable content in a collection

Articles share a shape: title, description, publication date, category, tags, language, and body. That makes them a strong fit for a build-time content collection.

const articles = defineCollection({
  loader: glob({
    base: "./src/content/articles",
    pattern: "**/*.md",
  }),
  schema: z.object({
    title: z.string(),
    description: z.string(),
    locale: z.enum(["en", "ar"]),
    publishedAt: z.coerce.date(),
    category: z.string(),
    tags: z.array(z.string()).default([]),
    draft: z.boolean().default(false),
  }),
});

The schema catches incomplete frontmatter during the build. It also gives components reliable types instead of optional values that every template must defend against.

Keep one-off pages such as About and Contact as Astro pages or focused page components. Moving every paragraph into a general-purpose data layer can make editing harder without providing a real benefit.

Keep route files thin

A dynamic article route should query entries, produce static paths, and pass one entry to the reading view. It should not contain the entire article design.

This separation makes English and Arabic routes small wrappers around the same presentation component. It also prevents fixes to metadata or the table of contents from being copied across route trees.

Use stable public slugs that are separate from internal collection IDs. The ID must be unique across all language files, while translated pages may intentionally share the same readable slug under different locale prefixes.

Make locale a first-class input

Do not discover the language from scattered pathname checks in every component. Pass a typed locale into shared page components and read labels, routes, direction, and date formatting from one translation module.

The document itself must set both lang and dir. Direction-aware CSS properties such as margin-inline, padding-inline, and border-inline-start reduce the number of RTL overrides.

Translated articles need a stable translationKey. That key connects English and Arabic entries even if their titles and public slugs later diverge.

Let layouts own metadata

The base layout should build the canonical URL, language alternates, Open Graph tags, RSS discovery, and shared structured data. The article view supplies the article-specific values and TechArticle schema.

This keeps SEO behavior consistent while allowing every page to have a unique title and description. It also makes a metadata change reviewable in one place.

Keep client JavaScript intentional

Most publication pages do not need a client framework. Theme switching, a disclosure menu, and simple archive filters can use small browser scripts. The article body, navigation, cards, and table of contents can remain static HTML.

If an interactive feature becomes complex enough for an island, load it with the least aggressive directive that matches when the visitor needs it.

Create one publishing path

A maintainable system makes the correct publishing workflow obvious:

  1. Add the article in the correct locale folder.
  2. Complete schema-validated frontmatter.
  3. Add or connect the translated entry.
  4. Run the production build.
  5. Review the generated URL, metadata, links, and reading layout.

The goal is not the most abstract component system. It is a content architecture where a future article is easier to publish than the previous one.

End of field note.