Advanced

Module Aliases

Using

Learn how to use Nuxt Umbu's module aliases (#auth-utils and #auth-types) for clean, type-safe imports throughout your application.

Overview

Nuxt Umbu provides two module aliases that simplify imports and provide full TypeScript support:

  • #auth-utils: Import utility functions and helpers
  • #auth-types: Import TypeScript type definitions

These aliases are automatically configured by the module and work in both client and server contexts.

Available Aliases

#auth-utils

The #auth-utils alias points to provider-specific utilities:

  • Sanctum: src/runtime/sanctum/utils/index.ts
  • Passport: src/runtime/passport/utils/index.ts

#auth-types

The #auth-types alias points to type definitions:

  • All providers: src/runtime/types/index.ts

Using #auth-utils

Importing Utilities

import { useAuthStore } from '#auth-utils'

const authStore = useAuthStore()

Available Utilities

The available utilities depend on your configured provider:

Sanctum Utilities

import { 
  useAuthStore,
  syncHeaders,
  ensureCsrf
} from '#auth-utils'

Passport Utilities

import { 
  useAuthStore,
  syncHeaders
} from '#auth-utils'

Common Usage Patterns

Auth Store

import { useAuthStore } from '#auth-utils'

// In a component
const authStore = useAuthStore()

// Access state
const user = computed(() => authStore.user)
const token = computed(() => authStore.token)
const strategy = computed(() => authStore.strategy)

// Call methods
await authStore.fetchUser()
await authStore.setToken('new-token')
await authStore.clearToken()

Header Synchronization

import { syncHeaders } from '#auth-utils'

// Sync headers with auth state
const headers = syncHeaders()

// Use in API calls
const response = await $fetch('/api/data', {
  headers: Object.fromEntries(headers.entries())
})

CSRF Protection (Sanctum)

import { ensureCsrf } from '#auth-utils'

// Ensure CSRF token is present
await ensureCsrf()

// Then make authenticated requests
const response = await $fetch('/api/protected', {
  method: 'POST',
  body: { data: 'value' }
})

Using #auth-types

Importing Types

import type { AuthInstance, ModuleOptions } from '#auth-types'

Common Type Imports

Core Types

import type { 
  AuthInstance,
  AuthState,
  ModuleOptions 
} from '#auth-types'

Provider Types

// Passport
import type { 
  PassportModuleOptions,
  PassportStrategiesOptions,
  AuthSecretConfig,
  AuthResponse,
  ProfileResponse 
} from '#auth-types'

// Sanctum
import type { 
  SanctumModuleOptions,
  SanctumStrategiesOptions,
  UserFetchOption 
} from '#auth-types'

Shared Types

import type { 
  CookieOption,
  AuthOptionsCookie,
  RedirectOptions 
} from '#auth-types'

Type Usage Examples

Typing Auth Instance

import type { AuthInstance } from '#auth-types'

const { $auth } = useNuxtApp()
const auth = $auth as AuthInstance

// Now fully typed
await auth.loginWith('password', { username: 'user', password: 'pass' })

Typing Configuration

import type { ModuleOptions, RedirectOptions } from '#auth-types'

const redirectConfig: RedirectOptions = {
  login: '/login',
  logout: '/',
  home: '/dashboard'
}

const authConfig: ModuleOptions = {
  provider: 'sanctum',
  redirect: redirectConfig,
  strategies: {
    default: {
      endpoints: {
        login: { url: '/login', method: 'post' },
        user: { url: '/api/user', method: 'get' }
      },
      redirect: redirectConfig
    }
  }
}

Typing Custom Functions

import type { AuthInstance } from '#auth-types'

async function loginAndFetchUser(
  auth: AuthInstance,
  credentials: Record<string, unknown>
) {
  await auth.loginWith('password', credentials)
  return auth.user
}

Alias Configuration

The aliases are automatically configured by the module:

Vite/Nitro Configuration

// Configured in module.ts
nuxt.options.alias['#auth-utils'] = runtimeUtilsPath
nuxt.options.alias['#auth-types'] = runtimeTypesPath

TypeScript Configuration

// Configured in prepare:types hook
tsConfig.compilerOptions.paths['#auth-utils'] = [runtimeUtilsPath]
tsConfig.compilerOptions.paths['#auth-types'] = [runtimeTypesPath]

Benefits of Using Aliases

Clean Imports

// Without aliases
import { useAuthStore } from '../../../runtime/sanctum/utils/index'
import type { AuthInstance } from '../../../runtime/types/index'

// With aliases
import { useAuthStore } from '#auth-utils'
import type { AuthInstance } from '#auth-types'

Provider Independence

// Works regardless of provider
import { useAuthStore } from '#auth-utils'

// Automatically uses correct provider implementation

Type Safety

// Full TypeScript support
import type { ModuleOptions } from '#auth-types'

const config: ModuleOptions = {
  // Type-checked configuration
}

Refactoring Friendly

// Change provider without updating imports
import { useAuthStore } from '#auth-utils'

// Alias automatically points to correct provider

Advanced Usage

Creating Custom Utilities

// utils/auth.ts
import { useAuthStore } from '#auth-utils'
import type { AuthInstance } from '#auth-types'

export function useCustomAuth() {
  const authStore = useAuthStore()
  const { $auth } = useNuxtApp()
  const auth = $auth as AuthInstance

  const login = async (credentials: { email: string; password: string }) => {
    return await auth.loginWith('password', credentials)
  }

  const logout = async () => {
    await auth.logout('password')
  }

  return {
    login,
    logout,
    user: computed(() => authStore.user),
    isLoggedIn: computed(() => authStore.strategy !== null)
  }
}

Type-Safe API Client

// utils/api.ts
import { syncHeaders } from '#auth-utils'
import type { AuthInstance } from '#auth-types'

export function createAuthApiClient(auth: AuthInstance) {
  return async <T = unknown>(
    url: string,
    options: RequestInit = {}
  ): Promise<T> => {
    const headers = syncHeaders()
    
    return await $fetch<T>(url, {
      ...options,
      headers: {
        ...Object.fromEntries(headers.entries()),
        ...options.headers
      }
    })
  }
}

Middleware with Aliases

// middleware/auth-check.ts
import { useAuthStore } from '#auth-utils'

export default defineNuxtRouteMiddleware((to, from) => {
  const authStore = useAuthStore()
  
  if (!authStore.strategy) {
    return navigateTo('/login')
  }
})

Server-Side Usage

Aliases work in server contexts as well:

// server/api/user.get.ts
import { useAuthStore } from '#auth-utils'
import type { AuthInstance } from '#auth-types'

export default defineEventHandler(async (event) => {
  const { $auth } = useNuxtApp(event)
  const auth = $auth as AuthInstance
  
  if (!auth.loggedIn) {
    throw createError({
      statusCode: 401,
      statusMessage: 'Unauthorized'
    })
  }
  
  return auth.user
})

Troubleshooting

Alias Not Recognized

If aliases aren't recognized:

  1. Restart your IDE
  2. Delete .nuxt folder and rebuild
  3. Check that the module is properly configured
  4. Verify TypeScript configuration

Type Errors with Aliases

If you get type errors:

// Ensure you're using 'type' keyword for type imports
import type { AuthInstance } from '#auth-types'

// Not
import { AuthInstance } from '#auth-types'

Wrong Provider Utils

If you're getting wrong utilities:

  1. Verify your provider configuration
  2. Check that the module setup completed successfully
  3. Restart the dev server after changing providers

Best Practices

  • Always use #auth-utils for utility imports
  • Always use #auth-types for type imports
  • Use type keyword for type-only imports
  • Create custom utilities that wrap the aliases
  • Leverage TypeScript for type safety
  • Keep imports at the top of files
  • Document custom utilities that use aliases

Migration from Relative Imports

If you're using relative imports, migrate to aliases:

Before

import { useAuthStore } from '../runtime/sanctum/utils/index'
import type { AuthInstance } from '../runtime/types/index'

After

import { useAuthStore } from '#auth-utils'
import type { AuthInstance } from '#auth-types'

IDE Support

Both VS Code and WebStorm fully support these aliases:

  • Autocomplete for imports
  • Go to definition
  • Find references
  • Rename symbol
  • Type checking

Summary

Module aliases provide:

  • Cleaner imports: No relative paths
  • Type safety: Full TypeScript support
  • Provider independence: Works with any provider
  • Better refactoring: Easier to maintain
  • IDE support: Full autocomplete and navigation