> ## 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.

# Page and card customization

> Extend host views and inject components into default pages or card cards.

You can customize existing pages and individual card layouts. The `customizePages` and `cards` namespaces provide layout slots for fine-grained modifications.

***

## Home page customization

The main **Home** page of LynxHub can be customized by replacing core sections or adding components around scroll grids.

```typescript theme={null}
// Replace default page sections
lynxAPI.customizePages.home.replace.searchAndFilter(Component: FC): void;
lynxAPI.customizePages.home.replace.searchResult(Component: FC<{searchValue: string}>): void;
lynxAPI.customizePages.home.replace.categories(Component: FC): void;

// Add elements around the main category grid
lynxAPI.customizePages.home.add.top(Component: FC): void;
lynxAPI.customizePages.home.add.bottom(Component: FC): void;
lynxAPI.customizePages.home.add.scrollTop(Component: FC): void;
lynxAPI.customizePages.home.add.scrollBottom(Component: FC): void;

// Append elements to categories sections
lynxAPI.customizePages.home.add.pinCategory(Component: FC): void;
lynxAPI.customizePages.home.add.recentlyCategory(Component: FC): void;
lynxAPI.customizePages.home.add.allCategory(Component: FC<CardDataProps>): void;
```

***

## Category-specific pages

You can inject components into standard category feeds (Audio, Image, Text, Agents, Others, Tools, Games). The slots are defined via a shared `PageAdd` structure:

```typescript theme={null}
// Available for: audio | image | text | agents | others | tools | games
lynxAPI.customizePages.tools.add.top(Component: FC): void;
lynxAPI.customizePages.tools.add.bottom(Component: FC): void;
lynxAPI.customizePages.tools.add.scrollTop(Component: FC): void;
lynxAPI.customizePages.tools.add.scrollBottom(Component: FC): void;
lynxAPI.customizePages.tools.add.cardsContainer(Component: FC): void;
```

### Example: Inject settings panel on the tools page

```jsx theme={null}
import ToolsPageSettings from './components/ToolsPageSettings';

export function InitialExtensions(lynxAPI) {
  // Adds a container settings block on the Tools category feed page
  lynxAPI.customizePages.tools.add.cardsContainer(ToolsPageSettings);
}
```

***

## Settings and dashboard pages

You can append new settings tabs or dashboard modules:

```typescript theme={null}
// Settings Page customization
lynxAPI.customizePages.settings.add.navButton(Component: FC): void;
lynxAPI.customizePages.settings.add.content(Component: FC): void;

// Dashboard Page customization
lynxAPI.customizePages.dashboard.add.navButton(Component: FC): void;
lynxAPI.customizePages.dashboard.add.content(Component: FC): void;
```

***

## Card layout customization

You can customize the card components that display card metadata in the feed.

```typescript theme={null}
import {CardData, LoadedCardData} from '@lynx_common/types/plugins/modules';

// Replace the entire cards grid list view
lynxAPI.cards.replace(Component: FC<{cards: LoadedCardData[]}>): void;

// Replace individual card layout cards
type CardDataProps = {
  useCardStore: UseCardStoreType;
  useCardOverlayState: typeof useCardOverlayState;
};
lynxAPI.cards.replaceComponent(Component: FC<CardDataProps>): void;

// Replace layout sections of default cards
lynxAPI.cards.customize.header(Component: FC<CardDataProps>): void;
lynxAPI.cards.customize.body(Component: FC<CardDataProps>): void;
lynxAPI.cards.customize.footer(Component: FC<CardDataProps>): void;
```

***

## Card menus and custom modals

You can append custom items to the options menu of each card, or link options to custom detail modals (e.g., verifying dependencies).

```typescript theme={null}
// Replace the entire options dropdown menu
lynxAPI.cards.customize.menu.replace(Component: FC<CardDataProps>): void;

// Append a menu item section at a specific index
type AddMenuType = {
  index: number;
  components: FC<CardDataProps>[];
};
lynxAPI.cards.customize.menu.addSection(sections: AddMenuType[]): void;

// Register custom options modal handlers
type AddModalType = {
  key: string;
  component: FC<CardDataProps>;
};
lynxAPI.cards.customize.menu.addModal(modals: AddModalType[]): void;
```

### Example: Card menu option triggers a modal

```jsx theme={null}
import CardMenuOption from './components/CardMenuOption';
import CardMenuModal from './components/CardMenuModal';

const DEPS_MODAL_KEY = 'python-toolkit-deps-modal';

export function InitialExtensions(lynxAPI) {
  // Add menu button
  lynxAPI.cards.customize.menu.addSection([
    {
      index: 1,
      components: [CardMenuOption],
    },
  ]);

  // Link button modal action key with the modal component
  lynxAPI.cards.customize.menu.addModal([
    {
      key: DEPS_MODAL_KEY,
      component: CardMenuModal,
    },
  ]);
}
```

***

## Custom Tools Cards

You can register custom cards directly into the **Tools** or **Games** sections of LynxHub using the `registerToolsCard` method:

```typescript theme={null}
lynxAPI.cards.registerToolsCard?.(config: {
  id: string;
  title: string;
  description: string;
  icon?: string | ReactNode;
  onPress?: () => void;
  component?: ComponentType;
  where?: string;
}): void;
```

### Example: Registering a custom Tools card

```jsx theme={null}
import PythonToolkitCard from './components/ToolsPage';

export function InitialExtensions(lynxAPI) {
  lynxAPI.cards.registerToolsCard?.({
    id: 'python-toolkit',
    title: 'Python Toolkit',
    description: 'Manage Python versions, virtual environments, packages, requirements and more.',
    component: PythonToolkitCard,
    where: 'tools_page',
  });
}
```
