Fix: Plugin Has No Default Export in Nuxt

Error message:
Plugin `{plugin.src}` has no default export and will be ignored at build time.
plugins 2025-01-25

What Causes This Error?

These warnings occur when your Nuxt plugin file doesn’t follow the required structure:

  1. No default export - Plugin file doesn’t export anything as default
  2. Not using defineNuxtPlugin - Plugin uses a plain function instead of the Nuxt wrapper

The Fix

Wrong: No Default Export

// ❌ Wrong - plugins/myPlugin.ts
export function myHelper() {
  return 'hello'
}

// Nothing is exported as default!

Wrong: Plain Function Export

// ❌ Wrong - plugins/myPlugin.ts
export default () => {
  console.log('Plugin loaded')
}

// Missing defineNuxtPlugin wrapper!

Correct: Using defineNuxtPlugin

// ✅ Correct - plugins/myPlugin.ts
export default defineNuxtPlugin((nuxtApp) => {
  console.log('Plugin loaded')
})

Complete Plugin Examples

Basic Plugin

// plugins/hello.ts
export default defineNuxtPlugin(() => {
  console.log('Hello from plugin!')
})

Plugin with Provide

// plugins/api.ts
export default defineNuxtPlugin(() => {
  const api = {
    get: (url: string) => $fetch(url),
    post: (url: string, data: any) => $fetch(url, { method: 'POST', body: data })
  }

  return {
    provide: {
      api
    }
  }
})

Usage:

<script setup>
const { $api } = useNuxtApp()
const data = await $api.get('/api/users')
</script>

Plugin with Hooks

// plugins/analytics.ts
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.hook('page:finish', () => {
    console.log('Page loaded')
  })

  nuxtApp.hook('app:error', (error) => {
    console.error('App error:', error)
  })
})

Plugin with Dependencies

// plugins/dependent.ts
export default defineNuxtPlugin({
  name: 'dependent-plugin',
  dependsOn: ['auth-plugin'],
  setup(nuxtApp) {
    // This runs after auth-plugin
  }
})

Async Plugin

// plugins/init.ts
export default defineNuxtPlugin(async (nuxtApp) => {
  // Async initialization
  const config = await $fetch('/api/config')

  return {
    provide: {
      config
    }
  }
})

Client-Only Plugin

// plugins/client-only.client.ts
export default defineNuxtPlugin(() => {
  // This only runs on client
  window.addEventListener('resize', () => {
    console.log('Window resized')
  })
})

Server-Only Plugin

// plugins/server-only.server.ts
export default defineNuxtPlugin(() => {
  // This only runs on server
  console.log('Server plugin initialized')
})

Plugin Object Syntax

For more control, use the object syntax:

// plugins/advanced.ts
export default defineNuxtPlugin({
  name: 'my-plugin',
  enforce: 'pre', // 'pre' | 'default' | 'post'
  async setup(nuxtApp) {
    // Setup logic
  },
  hooks: {
    'app:created'() {
      console.log('App created')
    }
  },
  env: {
    islands: true // Enable in component islands
  }
})

Common Mistakes

Mistake 1: Exporting Named Instead of Default

// ❌ Wrong
export const plugin = defineNuxtPlugin(() => {})

// ✅ Correct
export default defineNuxtPlugin(() => {})

Mistake 2: Using Regular Function

// ❌ Wrong
export default function() {
  console.log('Plugin')
}

// ✅ Correct
export default defineNuxtPlugin(() => {
  console.log('Plugin')
})

Mistake 3: Empty Plugin File

// ❌ Wrong - empty file or just imports
import something from 'somewhere'

// ✅ Correct - must have default export
import something from 'somewhere'
export default defineNuxtPlugin(() => {
  // Use something
})

TypeScript Plugin with Types

// plugins/typed.ts
declare module '#app' {
  interface NuxtApp {
    $hello: (name: string) => string
  }
}

export default defineNuxtPlugin(() => {
  return {
    provide: {
      hello: (name: string) => `Hello, ${name}!`
    }
  }
})

Quick Checklist

  • Plugin file has export default
  • Export uses defineNuxtPlugin() wrapper
  • Function receives nuxtApp parameter (if needed)
  • No syntax errors in plugin code
  • Async plugins use async keyword correctly
  • Plugin returns object with provide key (if providing values)