Back to Blog

Migrating from Directus to Nuxt Content: A Complete Guide

A
Allie
March 20, 2024
nuxtnuxt-contentcmsmigrationdirectusperformance

Migrating from Directus to Nuxt Content: A Complete Guide

Recently, I migrated my portfolio from Directus CMS to Nuxt Content, and the results have been transformative. Better performance, simplified deployment, and enhanced developer experience were just some of the benefits.

Why Make the Switch?

The Problems with External CMS

  • Deployment complexity: Managing separate CMS and frontend deployments
  • Network latency: API calls to external services
  • Build dependencies: Native module compilation issues (better-sqlite3)
  • Maintenance overhead: Keeping CMS updated and secure

Benefits of Nuxt Content

  • Git-based workflow: Content versioning with your code
  • Zero external dependencies: Everything runs locally
  • Better performance: No API calls, content is pre-processed
  • Simplified deployment: Single build process

The Migration Process

Step 1: Content Structure Setup

First, I organized content into logical directories:

content/
├── blog/
│   ├── dev/
│   └── tattoo/
├── projects/
├── gallery/
└── testimonials/

Step 2: Frontmatter Schema

Established consistent frontmatter for blog posts:

---
title: "Post Title"
date: "2024-03-20" 
description: "SEO description"
tags: ["tag1", "tag2"]
author: "Author Name"
published: true
featured: false
---

Step 3: Server API Routes

Created server endpoints to maintain API compatibility:

// server/api/content/blog/index.get.ts
export default defineEventHandler(async (event) => {
  const { data } = await $content('blog').find()
  return { data }
})

Step 4: Component Migration

Updated components to use new API endpoints:

<script setup>
// Before: Direct Directus calls
// const { data } = await directus.request(readItems('posts'))

// After: Local API
const { data } = await $fetch('/api/content/blog')
</script>

Key Configuration Changes

Nuxt Config

export default defineNuxtConfig({
  modules: ['@nuxt/content'],
  content: {
    experimental: {
      nativeSqlite: true // Avoids better-sqlite3 issues
    }
  }
})

Performance Optimizations

  • ISR (Incremental Static Regeneration): Cache content with periodic updates
  • Route rules: Optimize rendering strategy per page type
  • Image optimization: Built-in Nuxt Image module

Results

Performance Improvements

  • Build time: Reduced from 3-5 minutes to under 1 minute
  • Page load: 40% faster initial load times
  • Bundle size: Smaller due to removed API client libraries

Developer Experience

  • Local development: No external services needed
  • Content editing: Markdown files in your favorite editor
  • Version control: Content changes tracked with code changes

Migration Challenges

Data Migration

Converting CMS data to markdown required custom scripts:

// Export from Directus
const posts = await directus.request(readItems('posts'))

// Convert to markdown files
posts.forEach(post => {
  const frontmatter = {
    title: post.title,
    date: post.date_published,
    // ... other fields
  }
  
  const markdown = `---
${yaml.stringify(frontmatter)}---

${post.content}`
  
  fs.writeFileSync(`content/blog/${post.slug}.md`, markdown)
})

URL Structure

Maintained existing URLs by configuring routes:

// nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    routeRules: {
      '/blog/**': { isr: 3600 },
      '/projects/**': { isr: 3600 }
    }
  }
})

Best Practices

1. Content Organization

  • Use descriptive folder structures
  • Implement consistent naming conventions
  • Group related content logically

2. Frontmatter Standards

  • Define required vs optional fields
  • Use consistent date formats
  • Implement validation schemas

3. Image Management

  • Store images in public/ or use external CDN
  • Optimize images with Nuxt Image
  • Use descriptive alt text and filenames

4. SEO Considerations

  • Generate meta tags from frontmatter
  • Implement proper heading structure
  • Add structured data where relevant

Conclusion

Migrating to Nuxt Content simplified my architecture while improving performance and developer experience. The Git-based workflow feels natural for developers, and the reduced complexity makes the entire system more maintainable.

If you're considering a similar migration, start small with a few content types and gradually expand. The benefits compound as your content grows.

Resources

Happy migrating! 🚀

Author

About Allie

Developer and writer passionate about web technologies and creating user-friendly experiences.

Stay Updated

Subscribe to my newsletter to receive updates on new articles, tutorials, and resources.

Allison's Developer Portfolio

Full-stack developer specializing in modern web technologies

Contact

Feel free to reach out for collaborations or just a friendly hello

dev@allisons.dev

© 2026 Allison's Developer Portfolio. All rights reserved.

Built with using Nuxt, Nuxt UI, and Tailwind CSS