> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lynxhub.app/llms.txt
> Use this file to discover all available pages before exploring further.

# State, events, and routing

> Hook into client routing, system event emitters, and communicate with the main process.

Extensions can manage pages using client-side routers, communicate across processes with the IPC wrapper, and react to runtime lifecycle milestones through the system event emitter.

***

## Client-side routing and custom pages

You can add custom page components, register new client-side routes, or replace default view pages:

```typescript theme={null}
// Register a custom page to the router and sidebar navigation
lynxAPI.router.addPage(page: {
  id: string;
  title: string;
  icon?: ReactNode;
  component: FC;
  position?: 'top' | 'bottom' | 'hidden';
}): void;

// Register new client routes
lynxAPI.router.add(routes: RouteObject[]): void;

// Replace default pages entirely
lynxAPI.router.replace.homePage(Component: FC): void;
lynxAPI.router.replace.imageGenerationPage(Component: FC): void;
lynxAPI.router.replace.textGenerationPage(Component: FC): void;
lynxAPI.router.replace.audioGenerationPage(Component: FC): void;
lynxAPI.router.replace.toolsPage(Component: FC): void;
lynxAPI.router.replace.gamesPage(Component: FC): void;
lynxAPI.router.replace.dashboardPage(Component: FC): void;
lynxAPI.router.replace.modulesPage(Component: FC): void;
lynxAPI.router.replace.extensionsPage(Component: FC): void;
lynxAPI.router.replace.settingsPage(Component: FC): void;
```

***

## Event bus (`events`)

The Event Bus enables communication between the application host and active extensions. Use the `events` property on `lynxAPI`.

```typescript theme={null}
// Register listener. Returns unsubscribe function.
events.on(event: string, callback: (payload: any) => void): () => void;

// Remove listener
events.off(event: string, callback: (payload: any) => void): void;

// Emit custom events
events.emit(event: string, payload: any): void;

// Get listener count
events.getListenerCount(event: string): number;
```

### Hookable system events

The host emits events during critical application milestones:

| Event Name                | Payload Shape                    | Description                                                |
| :------------------------ | :------------------------------- | :--------------------------------------------------------- |
| `before_card_start`       | `{ id: string }`                 | Fires before launching a card module process.              |
| `before_card_install`     | `{ id: string }`                 | Fires before launching a card installation wizard.         |
| `card_install_addStep`    | `{ id: string, step: object }`   | Fires when registering a step in the installation stepper. |
| `card_collect_user_input` | `{ id: string, fields: object }` | Fires when collecting user configurations for a card.      |

***

## Renderer IPC (`rendererIpc`)

The `rendererIpc` object provides type-safe IPC wrappers to invoke methods or send events to your main process script.

```typescript theme={null}
// Invoke a main process handle method (Returns Promise)
rendererIpc.invoke<T = any>(channel: string, ...args: any[]): Promise<T>;

// Send a fire-and-forget message to the main process
rendererIpc.send(channel: string, ...args: any[]): void;

// Listen for messages from the main process. Returns cleanup function.
rendererIpc.on(channel: string, callback: (event: any, ...args: any[]) => void): () => void;
```

### Example: Invoking custom backend IPC

```typescript theme={null}
export function InitialExtensions(lynxAPI, rendererIpc) {
  rendererIpc.invoke('hardware:get-status').then(status => {
    console.log('CPU Load:', status.cpu);
  });
}
```

***

## Read-only modules data

The `modulesData` property grants access to loaded card modules information.

```typescript theme={null}
type ModuleData = {
  allModules: CardModules; // All modules loaded by application
  allCards: CardData[]; // Flat array of all card definitions

  // React hook to retrieve custom arguments for a card ID
  useGetArgumentsByID: (id: string) => ArgumentsData | undefined;

  // React hook to retrieve cards list belonging to a specific page ID
  useGetCardsByPath: (path: AvailablePageIDs) => LoadedCardData[] | undefined;

  // Retrieve a specific method from a card renderer methods object
  getCardMethod: (cards: CardData[], id: string, method: string) => Function | undefined;
};
```

***

## Toast indicators

You can trigger visual toast notifications:

```typescript theme={null}
lynxAPI.toast.top(message: string, options?: any): void;
lynxAPI.toast.bottom(message: string, options?: any): void;
```

***

## Tab navigation and control

You can programmatically navigate tabs or set the active page for the current active tab:

```typescript theme={null}
lynxAPI.tabs.setActivePage(pageID: string, title?: string, isTerminal?: boolean): void;
```

### Example: Navigate to a custom page on click

```jsx theme={null}
export function MySidebarWidget({lynxAPI}) {
  return <button onClick={() => lynxAPI.tabs.setActivePage('python-toolkit', 'Python Toolkit')}>Open Python Toolkit</button>;
}
```
