Fix: Invalid Route Component in Vue Router (Nuxt)

Error message:
Invalid route component for route: {path}
navigation 2025-01-25

What Causes This Error?

This error occurs when Vue Router tries to load a route component that is invalid, missing, or incorrectly exported. In Nuxt, this usually means there’s a problem with a file in the pages/ directory.

Common Causes

1. Component Has No Default Export

<!-- pages/about.vue -->
<!-- ❌ Wrong - no template, no default export -->
<script>
const data = 'hello'
</script>

<!-- ✅ Correct - has template or default export -->
<template>
  <div>About Page</div>
</template>

2. Empty or Invalid File

<!-- pages/broken.vue -->
<!-- ❌ Empty file -->

<!-- ✅ Minimum valid page -->
<template>
  <div>Content</div>
</template>

3. Syntax Error in Component

<!-- pages/error.vue -->
<script setup>
// ❌ Syntax error
const items = [1, 2, 3
</script>

<!-- ✅ Fixed -->
<script setup>
const items = [1, 2, 3]
</script>

<template>
  <div>{{ items }}</div>
</template>

4. Circular Dependencies

<!-- pages/a.vue -->
<script setup>
import B from '~/pages/b.vue'  // ❌ Importing page from page
</script>

<!-- ✅ Use components instead -->
<script setup>
import SharedComponent from '~/components/Shared.vue'
</script>

5. Import Errors

<script setup>
// ❌ Module doesn't exist
import { something } from 'nonexistent-package'

// ✅ Verify imports exist
import { ref } from 'vue'
</script>

The Fix

Verify File Structure

pages/
├── index.vue         ✅ Has template
├── about.vue         ✅ Has template
└── [id].vue          ✅ Has template

Minimum Valid Page

<!-- pages/minimal.vue -->
<template>
  <div>Page content</div>
</template>

With Script

<!-- pages/with-script.vue -->
<script setup>
const message = 'Hello'
</script>

<template>
  <div>{{ message }}</div>
</template>

With defineComponent

<!-- pages/classic.vue -->
<script>
export default defineComponent({
  setup() {
    return {
      message: 'Hello'
    }
  }
})
</script>

<template>
  <div>{{ message }}</div>
</template>

Debugging

Check for Syntax Errors

# Run TypeScript check
npx vue-tsc --noEmit

# Or check specific file
npx vue-tsc pages/problem.vue

Verbose Build

DEBUG=vite:* npm run dev

Check Route Registration

// nuxt.config.ts
export default defineNuxtConfig({
  hooks: {
    'pages:extend'(pages) {
      console.log('Registered pages:', pages.map(p => ({
        path: p.path,
        file: p.file
      })))
    }
  }
})

Dynamic Imports Issues

Lazy Loading Problems

// If manually registering routes
const routes = [
  {
    path: '/lazy',
    // ❌ Might fail if path is wrong
    component: () => import('~/pages/lazy.vue')
  }
]

// ✅ Verify path is correct
const routes = [
  {
    path: '/lazy',
    component: () => import('~/pages/lazy.vue').catch(err => {
      console.error('Failed to load:', err)
      return import('~/pages/error.vue')  // Fallback
    })
  }
]

Module Resolution

Check Aliases

// nuxt.config.ts
export default defineNuxtConfig({
  alias: {
    // Ensure aliases are correct
    '~': '/<rootDir>',
    '@': '/<rootDir>'
  }
})

Verify File Extensions

<script setup>
// ❌ Missing extension might cause issues
import MyComp from '~/components/MyComp'

// ✅ Explicit extension
import MyComp from '~/components/MyComp.vue'
</script>

TypeScript Issues

Type Errors Preventing Load

<script setup lang="ts">
// ❌ Type error might prevent component from loading
const user: User = {}  // Missing required properties

// ✅ Correct typing
interface User {
  name: string
  email: string
}
const user: User = {
  name: 'John',
  email: 'john@example.com'
}
</script>

Recovery Steps

1. Clear Cache

rm -rf .nuxt node_modules/.vite
npm run dev

2. Restart Dev Server

# Stop server (Ctrl+C)
# Start fresh
npm run dev

3. Check File Encoding

Ensure files are UTF-8 encoded without BOM.

4. Validate Vue Syntax

Use Volar extension in VS Code for real-time validation.

Quick Checklist

  • Page file has <template> section with content
  • No syntax errors in <script> section
  • All imports exist and are valid
  • No circular dependencies between pages
  • File is properly encoded (UTF-8)
  • Clear .nuxt cache and restart dev server
  • Check TypeScript errors with vue-tsc