Skip to content

Blog

How I'm Using MDX Frontmatter to Scale devportals.tech

Building devportals.tech has been an exercise in practicing what I preach about documentation engineering. One of the most impactful decisions I made early was leveraging MDX frontmatter not just for basic metadata, but as the foundation for scalable content workflows. Here’s how it’s working in practice.

When I first set up this Astro Starlight site, I could have just used basic Markdown. But knowing I wanted to build something that demonstrates professional documentation practices, I started with structured frontmatter from day one:

---
title: "Content Branching Strategy for Documentation Teams"
description: "How to manage documentation releases, staging, and quality control using Git workflows"
date: 2025-09-23
authors:
- name: Joaquin Romo
tags:
- git-workflow
- content-management
- documentation-strategy
- staging
---

Simple, but it’s already paying dividends.

As I’ve added more content to the site, patterns are emerging that I never planned but are incredibly valuable:

My tags are becoming a taxonomy that helps visitors (and me) understand the content landscape:

  • content-strategy for high-level planning topics
  • git-workflow for technical implementation details
  • documentation-strategy for process and methodology
  • astro-starlight for platform-specific insights

The Starlight Blog plugin automatically generates tag pages, so this creates navigation paths I didn’t have to manually build.

Even as the only author right now, having structured author metadata sets me up for:

  • Future collaboration - The schema is ready when I invite guest writers
  • Professional presentation - It shows I think about authorship professionally
  • Content attribution - If I repurpose content elsewhere, attribution is baked in

Every piece has a clear publication date, and I’m starting to add lastUpdated fields for major revisions. This helps me:

  • Track content freshness - I can see what might need updates
  • Show visitors currency - Recent dates build confidence
  • Plan maintenance - I can query for older content that needs review

The structured metadata makes my Git workflow much more manageable. When I’m working on new content in feature branches, I can easily see:

  • What’s ready to publish (clean frontmatter)
  • What needs more work (missing descriptions, placeholder content)
  • How content fits into the overall site structure

Having consistent frontmatter forces me to think about each piece:

  • What’s the actual value proposition? (title and description)
  • Who benefits from reading this? (tags and implicit audience)
  • How does this fit the larger narrative? (category and relationships)

It’s like having a checklist that ensures I’m not just writing, but creating strategic content.

I’m using Astro’s content collections with a schema that validates my frontmatter:

const blogSchema = z.object({
title: z.string(),
description: z.string(),
date: z.date(),
authors: z.array(z.object({
name: z.string()
})),
tags: z.array(z.string())
});

This catches mistakes early and ensures consistency. When I tried to publish a post with malformed dates or missing descriptions, the build failed with clear error messages.

As devportals.tech grows, I’m planning to leverage this metadata foundation for:

I want to build scripts that analyze my content patterns:

  • Which topics get the most tags (showing my focus areas)
  • Content gaps where I have few posts
  • Author productivity metrics (just for fun as a solo creator)

The structured data opens possibilities for:

  • “Related content” sections based on tag similarity
  • Topic clustering for themed reading paths
  • Content recommendations based on visitor interests

Rich metadata makes automated social media posts more meaningful. Instead of generic “new post” notifications, I can generate contextual descriptions that highlight the specific value each piece provides.

What I’m really doing is treating my personal documentation site like a product. The frontmatter discipline forces me to:

  • Think strategically about each piece of content
  • Build systems that scale beyond manual management
  • Demonstrate professionalism in how I approach documentation

For anyone building their own documentation site, I’d recommend starting with structured frontmatter even if you’re not sure how you’ll use it all. The discipline of thinking about metadata makes you a better content creator, and the flexibility enables capabilities you haven’t thought of yet.

The question isn’t whether you need metadata - it’s whether you want to build something that can grow intelligently or just accumulate content randomly.


Have you found creative ways to use frontmatter in your own documentation projects? I’d love to hear about approaches that have worked well for you.

Content Branching Strategy for Documentation Sites

When building a professional documentation site like DevPortals.tech, maintaining content quality while enabling rapid development requires a strategic approach to version control. Here’s the branching strategy I’ve implemented for managing documentation content lifecycle.

Building a portfolio-quality documentation site presents unique challenges:

  • Quality vs. Speed: You want to publish frequently but maintain professional standards
  • Work-in-Progress Content: Some sections need extensive research and iteration
  • Professional Presentation: Your live site represents your expertise to potential employers
  • Development Flexibility: You need space to experiment without affecting production

The Solution: Feature Branches for Content Sections

Section titled “The Solution: Feature Branches for Content Sections”

Instead of treating all documentation as a single unit, I organize content development around feature branches that correspond to major site sections.

Terminal window
main # Production-ready content only
├── docs-markup # Individual markup language deep-dives
├── docs-frameworks # Next.js vs Docusaurus detailed guides
├── docs-migration # Advanced migration case studies
├── docs-ai-tools # AI integration strategies
├── docs-resources # Curated tools and resources
└── docs-templates # Template library development

Real-World Example: Markup Languages Section

Section titled “Real-World Example: Markup Languages Section”

Here’s how I recently implemented this strategy:

I had created overview content for markup languages (Markdown, MDX, reStructuredText, AsciiDoc) but the individual deep-dive pages weren’t production-ready. I needed to:

  • Keep the excellent overview page live
  • Remove incomplete individual pages from production
  • Maintain development access to work on detailed content
Terminal window
# 1. Create feature branch
git checkout -b docs-markup
# 2. Move non-production files to staging
mkdir docs-markup-staging
mv src/content/docs/markup/{asciidoc,markdown,mdx,restructuredtext}.mdx docs-markup-staging/
# 3. Commit to feature branch
git add . && git commit -m "Move non-production markup files to staging"
# 4. Clean up main branch
git checkout main
rm src/content/docs/markup/{asciidoc,markdown,mdx,restructuredtext}.mdx
git add . && git commit -m "Keep only overview page in production"

When I want to work on the markup content:

Terminal window
# Switch to development branch
git checkout docs-markup
# Copy staging files for preview
cp docs-markup-staging/* src/content/docs/markup/
# Start development server
npm run dev
# Edit content with full preview capability
# Save changes back to staging when done
cp src/content/docs/markup/* docs-markup-staging/
# Commit progress
git add . && git commit -m "Improve markdown deep-dive content"
  • Production site stays clean: No placeholder or incomplete content
  • Professional presentation: Every live page meets publication standards
  • Confidence in sharing: Safe to include site URL in job applications
  • Experimental freedom: Try different approaches without consequences
  • Local preview capability: See changes before committing
  • Iterative improvement: Refine content over multiple sessions
  • Demonstrates workflow proficiency: Shows understanding of professional development practices
  • Version control expertise: Reflects enterprise-level Git knowledge
  • Content lifecycle management: Critical skill for platform roles
Terminal window
# Create and switch to feature branch
git checkout -b docs-[section-name]
# Develop content
# ... create and edit files ...
# Commit progress
git add . && git commit -m "Add [section] content framework"
# Push feature branch (optional, for backup)
git push origin docs-[section-name]
Terminal window
# Switch to feature branch
git checkout docs-[section-name]
# Copy staging content for preview (if applicable)
cp docs-[section]-staging/* src/content/docs/[section]/
# Start development
npm run dev
# Edit content...
# Save changes back to staging
cp src/content/docs/[section]/* docs-[section]-staging/
# Commit changes
git add . && git commit -m "Update [section] content"
Terminal window
# Ensure you're on main
git checkout main
# Merge feature branch
git merge docs-[section-name]
# Push to production
git push origin main # → Triggers deployment to live site
# Clean up (optional)
git branch -d docs-[section-name]
Terminal window
# For quick fixes to live content
git checkout main
# ... make changes ...
git add . && git commit -m "Fix typo in migration guide"
git push origin main
  • Professional portfolio sites: Where quality matters more than speed
  • Technical documentation: Content requiring research and iteration
  • Multi-author projects: Where review cycles are important
  • Long-form content: Guides, tutorials, comprehensive references
  • Simple blogs: Where immediate publishing is preferred
  • News sites: Where timeliness trumps perfection
  • Internal documentation: Where informal content is acceptable

Use descriptive prefixes that match your content structure:

  • docs- for documentation sections
  • feature- for new site functionality
  • fix- for bug fixes
  • content- for major content restructuring

For content that needs extensive development:

Terminal window
mkdir docs-[section]-staging
# Move incomplete files here
# Copy back for preview as needed

Consider shell scripts or aliases for common workflows:

Terminal window
# ~/.bashrc or ~/.zshrc
alias docs-preview="cp docs-*-staging/* src/content/docs/*/; npm run dev"
alias docs-save="cp src/content/docs/*/* docs-*-staging/"

This branching strategy transforms documentation development from a chaotic process into a professional workflow. It enables rapid iteration while maintaining production quality, demonstrates version control proficiency, and provides the confidence to share your work at any stage.

The key insight: treat your documentation site like enterprise software, with proper development, staging, and production environments. This approach not only improves your content quality but also showcases the systematic thinking that platform teams value.


This strategy has transformed how I approach documentation development, enabling both quality control and development velocity. How do you manage content lifecycle in your documentation projects?

Starlight Sidebar Configuration Strategies: Manual vs Autogenerate

While building DevPortals.tech, I ran into a common documentation site challenge: how do you organize sidebar navigation when you want some content to appear in a specific order (like overview pages) while still automatically including new files as you create them?

This is the kind of practical problem that comes up constantly when building documentation sites, and the solution isn’t always obvious from the docs.

I had a “Markup Languages” section with several files:

  • overview.mdx (should appear first)
  • asciidoc.mdx
  • markdown.mdx
  • mdx.mdx
  • restructuredtext.mdx

Using Starlight’s autogenerate feature, the sidebar was ordering files alphabetically, putting “overview” in the 4th position instead of first. Not ideal for user experience.

The most straightforward approach is to manually specify all sidebar items:

astro.config.mjs
{
label: 'Markup Languages',
items: [
{ label: 'Overview', link: '/markup/overview/' },
{ label: 'AsciiDoc', link: '/markup/asciidoc/' },
{ label: 'Markdown', link: '/markup/markdown/' },
{ label: 'MDX', link: '/markup/mdx/' },
{ label: 'reStructuredText', link: '/markup/restructuredtext/' },
],
}

Pros:

  • Complete control over order and labels
  • Can customize link text independently of file names
  • Clear and explicit configuration

Cons:

  • Manual maintenance required for new files
  • Easy to forget updating sidebar when adding content
  • More verbose configuration

Best for: Sections with stable content that rarely changes, or when you need custom labels.

Force alphabetical ordering by prefixing your overview file:

Terminal window
# Rename the file
mv src/content/docs/markup/overview.mdx src/content/docs/markup/00-overview.mdx

Then use autogenerate normally:

{
label: 'Markup Languages',
autogenerate: { directory: 'markup' },
}

Set the display title in frontmatter:

---
title: Overview # This shows in sidebar, not the filename
description: ...
---

Pros:

  • Maintains autogenerate benefits
  • Guaranteed ordering for important files
  • Simple implementation

Cons:

  • Ugly filenames with prefixes
  • Not semantically clean
  • Prefix strategy needs to be documented for team

Best for: Sections where you want mostly automatic management but need to pin a few key files.

Rename your overview to follow index file conventions:

Terminal window
mv src/content/docs/markup/overview.mdx src/content/docs/markup/index.mdx

Pros:

  • Semantic file naming
  • Works with autogenerate in Starlight
  • Follows web conventions (index files appear first)
  • Clean, professional approach

Cons:

  • Only works for one “special” file per directory
  • Less obvious what the file contains from filename alone

Best for: Sections where you have a clear introduction/overview page and the rest can be auto-managed.

Strategy 4: Mixed Manual + Autogenerate (Theoretical)

Section titled “Strategy 4: Mixed Manual + Autogenerate (Theoretical)”

This would be ideal but isn’t currently supported by Starlight:

// This doesn't work in Starlight (yet)
{
label: 'Markup Languages',
items: [
{ label: 'Overview', link: '/markup/overview/' },
{
label: 'Languages',
autogenerate: {
directory: 'markup',
exclude: ['overview.mdx']
},
},
],
}

Why it would be great:

  • Best of both worlds
  • Explicit control for key pages
  • Automatic inclusion of new content

Reality: Starlight doesn’t support exclude in autogenerate, so this approach isn’t available.

After testing all approaches, here’s my decision framework:

Use the index.mdx convention (Strategy 3). It’s semantic, clean, and works perfectly with autogenerate. This is what I implemented for the markup section.

Use manual items arrays (Strategy 1) when you have a well-defined set of content that rarely changes and you want custom labels.

Use filename prefixes (Strategy 2) when you’re actively adding content but need some ordering control. Accept the ugly filenames as a temporary trade-off.

Use straight autogenerate when alphabetical ordering is acceptable and you prioritize ease of maintenance.

This might seem like a small detail, but navigation organization directly impacts:

  • User experience: Can readers find what they need?
  • Content discoverability: Do overview pages get seen?
  • Maintenance overhead: How much work is adding new content?
  • Team adoption: Will other writers follow your patterns?

In my case, the index.mdx approach solved the immediate problem while keeping the configuration clean and maintainable.

Documentation tooling continues to evolve. I’d love to see Starlight add:

  • exclude patterns for autogenerate
  • Custom sorting functions
  • Mixed manual/auto approaches
  • Priority/weight-based ordering

Until then, these strategies provide good workarounds for common navigation challenges.


This post documents a real configuration challenge from building DevPortals.tech. What sidebar organization strategies have worked for your documentation sites?

From reST to MDX: Why Documentation Frameworks Are Evolving

Documentation frameworks are not just technical choices — they reflect cultural shifts in how we think about developer experience.

For years, reStructuredText (reST) powered serious technical documentation, especially in the Python and scientific communities.
Today, Markdown and MDX dominate modern developer portals. Why? Let’s explore this shift.


Origins:

  • Created for the Python ecosystem.
  • Strict, extensible, and great for generating reference documentation.
  • Closely tied to tools like Sphinx and ReadTheDocs.

Strengths:

  • Rigid grammar and semantic markup → consistency across docs.
  • Mature auto-documentation pipelines (e.g., autodoc with Sphinx).
  • Widely used in academic and scientific projects.

Challenges:

  • Verbose and harder to learn.
  • Contributions from non-experts can be intimidating.
  • Limited support for modern interactive or component-driven docs.

Why Markdown won:

  • Lightweight, readable, and easy to learn.
  • GitHub popularized it as the default for READMEs.
  • Perfect fit for docs-as-code workflows (PRs, reviews, version control).

Tradeoffs:

  • Less expressive than reST.
  • Needed extensions (like frontmatter, tables, or fenced code blocks) to catch up.

What it is:
MDX lets you write Markdown, but embed JSX (React components) directly into your docs.

Why it matters for dev portals:

  • Live code samples and sandboxes.
  • Reusable UI components inside content.
  • Docs can behave more like apps than static manuals.

In the wild:

  • Docusaurus (Meta’s framework).
  • Next.js with MDX plugins.
  • Astro Starlight (content-first with React/Vue/Svelte integrations).

  • Role Evolution: Technical writers → Documentation engineers.
  • Docs Evolution: Static reference → Dynamic experience.
  • Collaboration Evolution: Gatekeeping → Community contribution.

MD/MDX directly supports these cultural shifts by making docs easier to contribute to and more engaging for developers.


Despite the momentum of MD/MDX, reST continues to thrive in:

  • Python projects like Django, NumPy, and SciPy.
  • Scientific communities that value its rigor.
  • Legacy pipelines built around Sphinx extensions.

For many orgs, rewriting entire docsets is costly, so reST will persist in specialized contexts.


  • Momentum: MD/MDX frameworks are the present and future of dev portals.
  • Niche longevity: reST will survive in Python and academia.
  • Your takeaway: Framework choice isn’t only about syntax. It’s about workflows, interactivity, and alignment with developer expectations.

  • reST gave us rigor.
  • Markdown gave us accessibility.
  • MDX gives us interactivity.

This evolution mirrors the shift in developer portals themselves:
From manuals → to platforms → to experiences.

If you’re building a modern developer portal, understanding this history helps you make smarter choices today.


Building DevPortals.tech: From Idea to Live Site

As a senior technical writer who’s spent years managing enterprise documentation platforms, I’ve seen the pain points that drive teams to migrate from proprietary solutions to open-source alternatives.

This site chronicles that journey and provides practical guidance for teams making similar transitions.

After evaluating multiple documentation frameworks, Starlight stood out for several reasons:

  • Performance: Static site generation with minimal JavaScript
  • Developer Experience: Excellent TypeScript support and hot reload
  • Flexibility: Easy to extend and customize
  • Modern: Built for the current web ecosystem

I’m building additional demos in Next.js and Docusaurus to provide comprehensive framework comparisons for teams evaluating their options.

Stay tuned for more practical migration strategies and platform evaluations!