CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-jupyterlab--application

JupyterLab application framework providing the core application class, shell management, plugin system, layout restoration, and routing capabilities.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

url-routing.mddocs/

URL Routing

URL-based navigation system with pattern matching, command mapping, and programmatic route handling for single-page application behavior.

Capabilities

Router Class

Main router implementation providing URL routing with pattern matching and command execution for navigation within the application.

/**
 * URL routing implementation for applications
 */
class Router implements IRouter {
  constructor(options: Router.IOptions);
  
  /** The base URL for the router */
  readonly base: string;
  
  /** The command registry used by the router */
  readonly commands: CommandRegistry;
  
  /** The parsed current URL of the application */
  readonly current: IRouter.ILocation;
  
  /** A signal emitted when the router routes a route */
  readonly routed: ISignal<this, IRouter.ILocation>;
  
  /** Stop token for halting route matching chain */
  readonly stop: Token<void>;
  
  /**
   * Navigate to a new path within the application
   * @param path - The new path or empty string if redirecting to root
   * @param options - The navigation options
   */
  navigate(path: string, options?: IRouter.INavOptions): void;
  
  /**
   * Register a rule that maps a path pattern to a command
   * @param options - The route registration options
   * @returns A disposable that removes the registered rule from the router
   */
  register(options: IRouter.IRegisterOptions): IDisposable;
  
  /** Cause a hard reload of the document */
  reload(): void;
  
  /**
   * Route the current URL
   * @returns Promise that resolves when routing is complete
   */
  route(): Promise<void>;
}

Usage Examples:

import { Router, IRouter } from "@jupyterlab/application";
import { CommandRegistry } from "@lumino/commands";

// Create router
const commands = new CommandRegistry();
const router = new Router({
  base: '/lab',
  commands: commands
});

// Register commands first
commands.addCommand('app:open-file', {
  execute: (args) => {
    console.log('Opening file:', args.path);
  }
});

commands.addCommand('app:show-help', {
  execute: () => {
    console.log('Showing help');
  }
});

// Register route patterns
router.register({
  command: 'app:open-file',
  pattern: /^\/file\/(.+)$/,
  rank: 10
});

router.register({
  command: 'app:show-help', 
  pattern: /^\/help$/,
  rank: 20
});

// Navigate programmatically
router.navigate('/file/notebook.ipynb');
router.navigate('/help');

// Listen to route changes
router.routed.connect((sender, location) => {
  console.log('Routed to:', location.path);
});

// Current location info
console.log('Current path:', router.current.path);
console.log('Current hash:', router.current.hash);

IRouter Interface

Service interface for URL routing functionality with dependency injection support.

/**
 * URL routing service interface
 */
interface IRouter {
  /** The base URL for the router */
  readonly base: string;
  
  /** The command registry used by the router */
  readonly commands: CommandRegistry;
  
  /** The parsed current URL of the application */
  readonly current: IRouter.ILocation;
  
  /** A signal emitted when the router routes a route */
  readonly routed: ISignal<IRouter, IRouter.ILocation>;
  
  /** Stop token for halting route matching if returned from command */
  readonly stop: Token<void>;
  
  /**
   * Navigate to a new path within the application
   * @param path - The new path or empty string if redirecting to root
   * @param options - The navigation options
   */
  navigate(path: string, options?: IRouter.INavOptions): void;
  
  /**
   * Register a rule that maps a path pattern to a command
   * @param options - The route registration options
   * @returns A disposable that removes the registered rule from the router
   */
  register(options: IRouter.IRegisterOptions): IDisposable;
  
  /** Cause a hard reload of the document */
  reload(): void;
  
  /**
   * Route the current URL
   * @returns Promise that resolves when routing is complete
   * 
   * #### Notes
   * If a pattern is matched, its command will be invoked with arguments that
   * match the `IRouter.ILocation` interface.
   */
  route(): Promise<void>;
}

/**
 * Service token for URL router
 */
const IRouter: Token<IRouter>;

Usage in Plugins:

import { IRouter } from "@jupyterlab/application";
import { JupyterFrontEndPlugin } from "@jupyterlab/application";

const routingPlugin: JupyterFrontEndPlugin<void> = {
  id: 'my-routing-plugin',
  autoStart: true,
  requires: [IRouter],
  activate: (app, router: IRouter) => {
    // Register routes for this plugin
    const disposable = router.register({
      command: 'myapp:handle-route',
      pattern: /^\/myapp\/(.+)$/,
      rank: 100
    });
    
    // Listen to route changes
    router.routed.connect((sender, location) => {
      if (location.path.startsWith('/myapp/')) {
        console.log('My app route activated');
      }
    });
    
    // Clean up on plugin disposal
    return disposable;
  }
};

Location Interface

Information about the current URL location including parsed components.

/**
 * The parsed location currently being routed
 */
interface IRouter.ILocation extends ReadonlyPartialJSONObject {
  /** The location hash */
  hash: string;
  
  /** The path that matched a routing pattern */
  path: string;
  
  /** 
   * The request being routed with the router `base` omitted
   * 
   * #### Notes
   * This field includes the query string and hash, if they exist.
   */
  request: string;
  
  /** 
   * The search element, including leading question mark (`'?'`), if any,
   * of the path.
   */
  search?: string;
}

Usage Examples:

// Accessing location information
const currentLocation = router.current;

console.log('Full request:', currentLocation.request);
console.log('Path only:', currentLocation.path);
console.log('Hash:', currentLocation.hash);
console.log('Query string:', currentLocation.search);

// Example values for URL: /lab/tree/notebooks?filter=python#section1
// base: '/lab'
// request: '/tree/notebooks?filter=python#section1'  
// path: '/tree/notebooks'
// search: '?filter=python'
// hash: '#section1'

Navigation Options

Options for controlling navigation behavior and routing.

/**
 * The options passed into a navigation request
 */
interface IRouter.INavOptions {
  /** 
   * Whether the navigation should be hard URL change instead of an HTML
   * history API change.
   */
  hard?: boolean;
  
  /**
   * Should the routing stage be skipped when navigating? This will simply rewrite the URL
   * and push the new state to the history API, no routing commands will be triggered.
   */
  skipRouting?: boolean;
}

Usage Examples:

// Soft navigation (default) - uses HTML5 history API
router.navigate('/new-path');

// Hard navigation - causes full page reload
router.navigate('/new-path', { hard: true });

// Skip routing - just update URL without triggering commands
router.navigate('/new-path', { skipRouting: true });

// Combined options
router.navigate('/external-link', { 
  hard: true,
  skipRouting: false 
});

Route Registration

System for mapping URL patterns to commands with configurable priority.

/**
 * The specification for registering a route with the router
 */
interface IRouter.IRegisterOptions {
  /** The command string that will be invoked upon matching */
  command: string;
  
  /** The regular expression that will be matched against URLs */
  pattern: RegExp;
  
  /** 
   * The rank order of the registered rule. A lower rank denotes a higher
   * priority. The default rank is `100`.
   */
  rank?: number;
}

Usage Examples:

// High priority route (lower rank = higher priority)
router.register({
  command: 'app:admin-panel',
  pattern: /^\/admin\/(.*)$/,
  rank: 1
});

// Medium priority route
router.register({
  command: 'app:open-notebook',
  pattern: /^\/notebooks\/(.+\.ipynb)$/,
  rank: 50
});

// Default priority route (rank defaults to 100)
router.register({
  command: 'app:catch-all',
  pattern: /^\/(.*)$/
});

// Route with capture groups
router.register({
  command: 'app:user-profile',
  pattern: /^\/users\/([^\/]+)(?:\/(.+))?$/,
  rank: 25
});

// Command handler receives location as arguments
commands.addCommand('app:user-profile', {
  execute: (args: IRouter.ILocation) => {
    // Access path parts via regex match
    const match = args.path.match(/^\/users\/([^\/]+)(?:\/(.+))?$/);
    if (match) {
      const [, username, subpath] = match;
      console.log('User:', username, 'Subpath:', subpath);
    }
  }
});

Constructor Options

Configuration for creating Router instances.

namespace Router {
  /**
   * Constructor options for Router
   */
  interface IOptions {
    /** Base URL path for the router */
    base: string;
    
    /** Command registry to use for route commands */
    commands: CommandRegistry;
  }
}

Usage Examples:

import { Router } from "@jupyterlab/application";
import { CommandRegistry } from "@lumino/commands";

// Basic router setup
const commands = new CommandRegistry();
const router = new Router({
  base: window.location.pathname,
  commands: commands
});

// Router with custom base
const labRouter = new Router({
  base: '/lab',
  commands: commands
});

// Router for development
const devRouter = new Router({
  base: process.env.NODE_ENV === 'development' ? '/dev' : '/app',
  commands: commands
});

Advanced Routing Patterns

Complex routing scenarios and patterns for real-world applications.

// Advanced routing patterns
interface AdvancedRoutingPatterns {
  /** File path routing with extension matching */
  fileRouting: RegExp; // /^\/files\/(.+\.(py|js|ts|md))$/
  
  /** Nested resource routing */
  nestedRouting: RegExp; // /^\/workspaces\/([^\/]+)\/files\/(.+)$/
  
  /** Optional parameters */
  optionalParams: RegExp; // /^\/search(?:\/(.+))?$/
  
  /** Query parameter handling */
  queryParams: RegExp; // /^\/results/
}

Complete Routing Example:

import { Router, IRouter } from "@jupyterlab/application";
import { CommandRegistry } from "@lumino/commands";

// Complete routing setup
function setupRouting(commands: CommandRegistry): Router {
  const router = new Router({
    base: '/app',
    commands: commands
  });
  
  // Define commands
  commands.addCommand('app:home', {
    execute: () => console.log('Home page')
  });
  
  commands.addCommand('app:open-file', {
    execute: (args: IRouter.ILocation) => {
      const match = args.path.match(/^\/files\/(.+)$/);
      if (match) {
        const filePath = decodeURIComponent(match[1]);
        console.log('Opening file:', filePath);
      }
    }
  });
  
  commands.addCommand('app:search', {
    execute: (args: IRouter.ILocation) => {
      const searchParams = new URLSearchParams(args.search || '');
      const query = searchParams.get('q') || '';
      console.log('Searching for:', query);
    }
  });
  
  // Register routes with priorities
  const disposables = [
    // High priority exact matches
    router.register({
      command: 'app:home',
      pattern: /^\/$/,
      rank: 1
    }),
    
    // Medium priority with parameters
    router.register({
      command: 'app:open-file',
      pattern: /^\/files\/(.+)$/,
      rank: 50
    }),
    
    router.register({
      command: 'app:search',
      pattern: /^\/search$/,
      rank: 50
    })
  ];
  
  // Navigation helpers
  const navigateToFile = (path: string) => {
    router.navigate(`/files/${encodeURIComponent(path)}`);
  };
  
  const navigateToSearch = (query: string) => {
    router.navigate(`/search?q=${encodeURIComponent(query)}`);
  };
  
  // Route change logging
  router.routed.connect((sender, location) => {
    console.log(`Routed to: ${location.path}`, location);
  });
  
  return router;
}

Error Handling

Handling routing errors and edge cases.

// Error handling in route commands
commands.addCommand('app:error-prone-route', {
  execute: async (args: IRouter.ILocation) => {
    try {
      // Route handling that might fail
      await handleRoute(args);
    } catch (error) {
      console.error('Route handling failed:', error);
      // Navigate to error page or show notification
      router.navigate('/error');
    }
  }
});

// Graceful fallback routing
router.register({
  command: 'app:not-found',
  pattern: /.*/,  // Matches everything
  rank: 1000     // Lowest priority (highest rank)
});

docs

application-framework.md

index.md

layout-restoration.md

mime-rendering.md

service-tokens.md

shell-management.md

status-management.md

url-routing.md

utility-functions.md

tile.json