CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-nuxt

Nuxt is a free and open-source framework with an intuitive and extendable way to create type-safe, performant and production-grade full-stack web applications and websites with Vue.js.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

navigation.mddocs/

Navigation & Routing

Vue Router integration with programmatic navigation, route middleware, and layout management. Nuxt provides enhanced routing capabilities with file-based routing, nested layouts, and powerful navigation utilities.

Note: This module uses Vue Router types. In a real application, these are available through Nuxt's auto-imports or can be imported from 'vue-router'.

Capabilities

Router Access

Access Vue Router instance and current route information.

/**
 * Get the Vue Router instance
 * @returns Vue Router instance
 */
function useRouter(): Router;

/**
 * Get the current route information  
 * @returns Current route object with params, query, meta, etc.
 */
function useRoute(): RouteLocationNormalizedLoaded;

interface Router {
  /** Navigate to a route */
  push(to: RouteLocationRaw): Promise<NavigationFailure | void | undefined>;
  /** Replace current route */
  replace(to: RouteLocationRaw): Promise<NavigationFailure | void | undefined>;
  /** Go back in history */
  back(): void;
  /** Go forward in history */
  forward(): void;
  /** Go to specific history position */
  go(delta: number): void;
  /** Add route dynamically */
  addRoute(route: RouteRecordRaw): () => void;
  /** Remove route by name */
  removeRoute(name: string | symbol): void;
  /** Check if route exists */
  hasRoute(name: string | symbol): boolean;
  /** Get all routes */
  getRoutes(): RouteRecord[];
  /** Resolve route location */
  resolve(to: RouteLocationRaw): RouteLocation & { href: string };
  /** Current route */
  currentRoute: Readonly<Ref<RouteLocationNormalizedLoaded>>;
  /** Navigation guards */
  beforeEach(guard: NavigationGuardWithThis<undefined>): () => void;
  beforeResolve(guard: NavigationGuardWithThis<undefined>): () => void;
  afterEach(guard: NavigationHookAfter): () => void;
}

interface RouteLocationNormalizedLoaded {
  /** Route name */
  name?: string | symbol;
  /** Route path */
  path: string;
  /** Route parameters */
  params: RouteParams;
  /** Query parameters */
  query: LocationQuery;
  /** Hash fragment */
  hash: string;
  /** Route meta information */
  meta: RouteMeta;
  /** Full URL including domain */
  fullPath: string;
  /** Matched route records */
  matched: RouteRecordNormalized[];
  /** Redirected from route */
  redirectedFrom?: RouteLocation;
}

Usage Examples:

// Get router and route
const router = useRouter();
const route = useRoute();

// Access route information
console.log("Current path:", route.path);
console.log("Route params:", route.params);
console.log("Query params:", route.query);
console.log("Route name:", route.name);

// Router navigation
await router.push("/users");
await router.push({ name: "users-id", params: { id: "123" } });
await router.replace("/home");

// History navigation
router.back();
router.forward();
router.go(-2);

// Dynamic routes
router.addRoute({
  name: "admin",
  path: "/admin/:section",
  component: AdminComponent,
  meta: { requiresAuth: true }
});

// Watch route changes
watch(route, (to, from) => {
  console.log(`Navigated from ${from.path} to ${to.path}`);
});

// Reactive route parameters
const userId = computed(() => route.params.id);
watch(userId, (newId) => {
  if (newId) {
    fetchUser(newId);
  }
});

Programmatic Navigation

Navigate programmatically with enhanced features and error handling.

/**
 * Navigate to a route programmatically
 * @param to - Route location to navigate to
 * @param options - Navigation options
 * @returns Navigation result or redirect response
 */
function navigateTo(
  to: RouteLocationRaw,
  options?: NavigateToOptions
): Promise<void | NavigationFailure | false> | false | void;

/**
 * Abort the current navigation
 * @param err - Optional error information
 */
function abortNavigation(err?: string | Partial<NuxtError>): void;

interface NavigateToOptions {
  /** Replace current route instead of pushing */
  replace?: boolean;
  /** HTTP redirect code for SSR */
  redirectCode?: number;
  /** Navigate to external URL */
  external?: boolean;
  /** Open in new window/tab */
  open?: {
    target: string;
    windowFeatures?: Record<string, any>;
  };
}

Usage Examples:

// Basic navigation
await navigateTo("/users");

// With parameters
await navigateTo(`/users/${userId}`);
await navigateTo({ name: "users-id", params: { id: userId } });

// With query parameters
await navigateTo({
  path: "/search",
  query: { q: "nuxt", category: "framework" }
});

// Replace current route
await navigateTo("/home", { replace: true });

// External navigation
await navigateTo("https://nuxt.com", { external: true });

// Open in new tab
await navigateTo("/docs", {
  open: { 
    target: "_blank",
    windowFeatures: {
      width: 1200,
      height: 800
    }
  }
});

// Server-side redirects
await navigateTo("/login", { redirectCode: 302 });

// Conditional navigation
if (!user.value) {
  await navigateTo("/login");
}

// Navigation with error handling
try {
  await navigateTo("/protected-route");
} catch (error) {
  console.error("Navigation failed:", error);
  await navigateTo("/error");
}

// Abort navigation
function onBeforeLeave() {
  if (hasUnsavedChanges.value) {
    abortNavigation("You have unsaved changes");
  }
}

Route Middleware

Add and manage route middleware for authentication, authorization, and other route-level logic.

/**
 * Add route middleware dynamically
 * @param name - Middleware name or function
 * @param middleware - Middleware function if name is string
 * @param options - Middleware options
 */
function addRouteMiddleware(
  name: string | RouteMiddleware,
  middleware?: RouteMiddleware,
  options?: AddRouteMiddlewareOptions
): void;

/**
 * Define route middleware with proper typing
 * @param middleware - Middleware function
 * @returns The middleware function
 */
function defineNuxtRouteMiddleware(middleware: RouteMiddleware): RouteMiddleware;

type RouteMiddleware = (
  to: RouteLocationNormalized,
  from: RouteLocationNormalized
) => NavigationGuardReturn | Promise<NavigationGuardReturn>;

interface AddRouteMiddlewareOptions {
  /** Whether middleware is global */
  global?: boolean;
}

type NavigationGuardReturn = 
  | void 
  | Error 
  | RouteLocationRaw 
  | boolean 
  | NavigationGuardNextCallback;

Usage Examples:

// Define middleware inline
addRouteMiddleware((to) => {
  if (to.path === "/admin" && !user.value?.isAdmin) {
    return navigateTo("/login");
  }
});

// Define named middleware
addRouteMiddleware("auth", (to) => {
  if (!user.value) {
    return navigateTo("/login");
  }
});

// Global middleware
addRouteMiddleware("track-analytics", (to) => {
  analytics.page(to.path);
}, { global: true });

// Middleware in separate file (middleware/auth.ts)
export default defineNuxtRouteMiddleware((to) => {
  const { user } = useAuth();
  
  if (!user.value) {
    throw createError({
      statusCode: 401,
      statusMessage: "Authentication required"
    });
  }
});

// Complex middleware with async operations
defineNuxtRouteMiddleware(async (to) => {
  const { user, refresh } = useAuth();
  
  // Refresh user data if needed
  if (!user.value) {
    await refresh();
  }
  
  // Check permissions
  const hasPermission = await checkUserPermission(to.meta.permission);
  if (!hasPermission) {
    throw createError({
      statusCode: 403,
      statusMessage: "Insufficient permissions"
    });
  }
});

// Middleware with redirect
defineNuxtRouteMiddleware((to) => {
  const { user } = useAuth();
  
  if (to.path.startsWith("/admin") && user.value?.role !== "admin") {
    return navigateTo("/dashboard");
  }
  
  if (to.path === "/profile" && !user.value?.emailVerified) {
    return navigateTo("/verify-email");
  }
});

Navigation Guards

Set up navigation guards for component-level route handling.

/**
 * Add route leave guard
 * @param guard - Navigation guard function
 */
function onBeforeRouteLeave(guard: NavigationGuard): void;

/**
 * Add route update guard  
 * @param guard - Navigation guard function
 */
function onBeforeRouteUpdate(guard: NavigationGuard): void;

type NavigationGuard = (
  to: RouteLocationNormalized,
  from: RouteLocationNormalized,
  next: NavigationGuardNext
) => NavigationGuardReturn | Promise<NavigationGuardReturn>;

Usage Examples:

// Prevent leaving with unsaved changes
onBeforeRouteLeave((to, from, next) => {
  if (hasUnsavedChanges.value) {
    const answer = confirm("You have unsaved changes. Do you really want to leave?");
    if (answer) {
      next();
    } else {
      next(false);
    }
  } else {
    next();
  }
});

// Handle route parameter changes
onBeforeRouteUpdate(async (to, from) => {
  if (to.params.id !== from.params.id) {
    await fetchUser(to.params.id);
  }
});

// Save scroll position
onBeforeRouteLeave(() => {
  const scrollPosition = window.scrollY;
  sessionStorage.setItem(`scroll-${route.path}`, scrollPosition.toString());
});

Layout Management

Manage page layouts dynamically.

/**
 * Set the layout for the current page
 * @param layout - Layout name to use
 */
function setPageLayout(layout: string): void;

Usage Examples:

// Set layout based on user role
const { user } = useAuth();
watch(user, (newUser) => {
  if (newUser?.role === "admin") {
    setPageLayout("admin");
  } else {
    setPageLayout("default");
  }
});

// Conditional layout
if (route.path.startsWith("/dashboard")) {
  setPageLayout("dashboard");
}

// Mobile vs desktop layout
const isMobile = useMediaQuery("(max-width: 768px)");
watch(isMobile, (mobile) => {
  setPageLayout(mobile ? "mobile" : "desktop");
});

Advanced Navigation Patterns

// Breadcrumb navigation
const breadcrumbs = computed(() => {
  const matched = route.matched.filter(record => record.meta?.breadcrumb);
  return matched.map(record => ({
    name: record.meta.breadcrumb,
    path: record.path,
    params: route.params
  }));
});

// Tab navigation with query sync
const activeTab = computed({
  get: () => route.query.tab || "overview",
  set: (tab) => {
    router.push({
      query: { ...route.query, tab }
    });
  }
});

// Search with history
const searchQuery = ref("");
const searchHistory = useState<string[]>("search-history", () => []);

const performSearch = async (query: string) => {
  // Add to history
  if (query && !searchHistory.value.includes(query)) {
    searchHistory.value.unshift(query);
    searchHistory.value = searchHistory.value.slice(0, 10); // Keep last 10
  }
  
  // Navigate with query
  await navigateTo({
    path: "/search",
    query: { q: query }
  });
};

// Route-based modal
const showModal = computed(() => route.query.modal === "true");

const openModal = () => {
  router.push({
    query: { ...route.query, modal: "true" }
  });
};

const closeModal = () => {
  const { modal, ...query } = route.query;
  router.push({ query });
};

// Multi-step form navigation
const currentStep = computed(() => 
  parseInt(route.params.step as string) || 1
);

const nextStep = () => {
  const next = currentStep.value + 1;
  router.push({
    name: "form-step",
    params: { step: next.toString() }
  });
};

const previousStep = () => {
  if (currentStep.value > 1) {
    const prev = currentStep.value - 1;
    router.push({
      name: "form-step", 
      params: { step: prev.toString() }
    });
  }
};

Types

type RouteLocationRaw = string | RouteLocationPathRaw | RouteLocationNamedRaw;

interface RouteLocationPathRaw {
  path: string;
  query?: LocationQueryRaw;
  hash?: string;
}

interface RouteLocationNamedRaw {
  name: string | symbol;
  params?: RouteParamsRaw;
  query?: LocationQueryRaw;
  hash?: string;
}

type RouteParams = Record<string, string | string[]>;
type RouteParamsRaw = Record<string, string | string[] | number | number[]>;
type LocationQuery = Record<string, string | string[]>;
type LocationQueryRaw = Record<string, string | string[] | number | number[] | null | undefined>;

interface RouteMeta {
  [key: string | number | symbol]: unknown;
}

interface RouteRecordRaw {
  path: string;
  name?: string | symbol;
  component?: Component;
  components?: Record<string, Component>;
  redirect?: RouteLocationRaw | ((to: RouteLocationNormalized) => RouteLocationRaw);
  alias?: string | string[];
  children?: RouteRecordRaw[];
  meta?: RouteMeta;
  props?: boolean | Record<string, any> | ((to: RouteLocationNormalized) => Record<string, any>);
  beforeEnter?: NavigationGuardWithThis<undefined> | NavigationGuardWithThis<undefined>[];
  sensitive?: boolean;
  strict?: boolean;
}

interface NavigationFailure extends Error {
  type: NavigationFailureType;
  from: RouteLocationNormalized;
  to: RouteLocationNormalized;
}

enum NavigationFailureType {
  aborted = 4,
  cancelled = 8,
  duplicated = 16
}

type NavigationGuardNext = (to?: RouteLocationRaw | false | ((vm: ComponentPublicInstance) => any) | void) => void;

type NavigationGuardNextCallback = (vm: ComponentPublicInstance) => any;

type NavigationGuardWithThis<T> = (
  this: T,
  to: RouteLocationNormalized,
  from: RouteLocationNormalized,
  next: NavigationGuardNext
) => NavigationGuardReturn | Promise<NavigationGuardReturn>;

type NavigationHookAfter = (
  to: RouteLocationNormalized,
  from: RouteLocationNormalized,
  failure?: NavigationFailure | void
) => any;

Accessibility Features

Accessibility utilities for route announcements and screen reader support.

/**
 * Set up route announcements for screen readers
 * @param opts - Configuration options for route announcer
 * @returns Route announcer utilities
 */
function useRouteAnnouncer(opts?: RouteAnnouncerOptions): RouteAnnouncer;

interface RouteAnnouncerOptions {
  /** ARIA politeness level for announcements */
  politeness?: 'polite' | 'assertive';
  /** Skip announcement for these routes */
  skipRoutes?: string[];
  /** Custom message formatter */
  formatMessage?: (route: RouteLocationNormalized) => string;
}

interface RouteAnnouncer {
  /** Announce current route */
  announce(): void;
  /** Skip next announcement */
  skip(): void;
  /** Set custom announcement message */
  set(message: string): void;
}

Usage Example:

<script setup>
import { useRouteAnnouncer } from "nuxt/app";

const announcer = useRouteAnnouncer({
  politeness: 'polite',
  skipRoutes: ['/api'],
  formatMessage: (route) => `Navigated to ${route.meta.title || route.path}`
});

// Manually announce
announcer.announce();

// Skip next automatic announcement
announcer.skip();

// Custom announcement
announcer.set('Welcome to the dashboard');
</script>

Additional Types

interface RouteAnnouncerOptions {
  /** ARIA politeness level for announcements */
  politeness?: 'polite' | 'assertive';
  /** Skip announcement for these routes */
  skipRoutes?: string[];
  /** Custom message formatter */
  formatMessage?: (route: RouteLocationNormalized) => string;
}

interface RouteAnnouncer {
  /** Announce current route */
  announce(): void;
  /** Skip next announcement */
  skip(): void;
  /** Set custom announcement message */
  set(message: string): void;
}

Install with Tessl CLI

npx tessl i tessl/npm-nuxt

docs

app-lifecycle.md

configuration.md

core.md

data-fetching.md

head.md

index.md

module-dev.md

navigation.md

performance.md

ssr.md

state.md

tile.json