---
title: SFC Script Block Must Use Default Export Only
impact: HIGH
impactDescription: Named exports in SFC script blocks will fail silently or cause build errors - Vue expects exactly one default export
type: gotcha
tags: [vue3, sfc, export, script-block, composition-api]
---
# SFC Script Block Must Use Default Export Only
**Impact: HIGH** - Vue Single-File Components expect exactly one default export from the `
{{ count }}
```
**Correct Code:**
```vue
{{ count }}
```
```vue
{{ count }}
```
## Exporting Types Alongside Script Setup
For TypeScript, use a separate regular script block for type exports:
```vue
```
## Sharing Utilities Across Components
Don't put shared code in component script blocks. Create separate files:
```typescript
// utils/constants.ts
export const ITEMS_PER_PAGE = 20
export const API_BASE_URL = '/api/v1'
// utils/helpers.ts
export function formatDate(date: Date): string {
return date.toLocaleDateString()
}
export function formatCurrency(amount: number): string {
return `$${amount.toFixed(2)}`
}
```
```vue
```
## Why This Restriction Exists
Vue's SFC compiler and build tools expect:
1. **One component per file**: The `.vue` file format is designed for single-component definitions
2. **Predictable structure**: Tools like Volar, vue-tsc, and bundler plugins assume default export
3. **Hot Module Replacement**: HMR relies on the single-component-per-file convention
```javascript
// How Vue tooling processes SFCs internally
import MyComponent from './MyComponent.vue'
// ^ Always expects the default export to be the component
```
## Common Mistake: Reusing Code via SFC Exports
```vue
```
Instead, use composables:
```typescript
// composables/useSharedLogic.ts
export function useSharedLogic() {
// Shared reactive logic
const state = ref(0)
const increment = () => state.value++
return { state, increment }
}
```
```vue
```
## Reference
- [Vue.js SFC Specification](https://vuejs.org/api/sfc-spec.html)
- [Vue.js Composition API - Composables](https://vuejs.org/guide/reusability/composables.html)