# Superfile Sidebar Architecture and Pinned Directories Management

> Explore Superfile's sidebar architecture a hybrid system combining static TypeScript trees with dynamic JSON pinned directories for flexible documentation and custom workflows.

- Repository: [Yorukot/superfile](https://github.com/yorukot/superfile)
- Tags: architecture
- Published: 2026-07-28

---

**Superfile implements a hybrid navigation system that combines a static, TypeScript-defined sidebar tree with dynamic user-pinned directories stored in JSON configuration, enabling immutable documentation structure alongside customizable user workflows.**

The yorukot/superfile repository structures its interface navigation through a declarative static model while persisting user-specific shortcuts via runtime configuration. This architectural pattern strictly separates immutable navigation elements from mutable user preferences, creating a predictable yet flexible browsing experience.

## Static Navigation Tree Structure

The foundation of Superfile’s sidebar resides in [`website/src/lib/navigation.ts`](https://github.com/yorukot/superfile/blob/main/website/src/lib/navigation.ts), which exports a strictly typed navigation hierarchy. This file defines the immutable structure of the documentation and interface navigation through distinct interfaces that differentiate between single links and collapsible groups.

### Core Navigation Interfaces

The type system distinguishes between leaf nodes and container nodes using two primary interfaces:

```typescript
export interface NavLeaf {
    label: string;
    slug: string;
    zhLabel?: string;
}

export interface NavGroup {
    label: string;
    zhLabel?: string;
    items: NavLeaf[];
}

export type NavNode = NavLeaf | NavGroup;

```

Each `NavLeaf` represents a terminal navigation destination with a display label, URL slug, and optional Chinese translation label. The `NavGroup` interface creates collapsible sections containing multiple leaf items, enabling organized categorization of documentation sections like "Start Here", "Configure", and "Contribute".

### Navigation Utilities

To facilitate traversal and sequential navigation, the module exports two critical helper functions:

- **`flattenNav()`**: Recursively walks the navigation tree and produces a flat, ordered array of `NavLeaf` objects while preserving the hierarchical declaration order.
- **`getPrevNext(slug)`**: Accepts a URL slug parameter, locates it within the flattened navigation array, and returns references to the immediately preceding and succeeding entries.

These utilities power breadcrumb generation, documentation "previous/next" pagination controls, and ordered traversal of the navigation structure without requiring repeated tree-walking operations.

## Pinned Directories Runtime Management

Unlike the static navigation tree, pinned directories represent mutable user state that persists across sessions. Superfile maintains these preferences in a user-specific configuration file rather than in the source code.

### Configuration Storage

Pinned directories reside in `~/.superfile/config.json` as an array of absolute paths within a `pinned` property. This location is user-specific and runtime-dependent, allowing each installation to maintain independent shortcut lists without modifying the application source or rebuilding the navigation structure.

### Display and Interaction

During application startup, Superfile performs the following sequence:

1. **Loading**: Reads and parses the JSON configuration file, extracting the `pinned` array.
2. **Rendering**: Injects a dedicated "Pinned" section at the top of the sidebar, treating each directory path as a dynamic `NavLeaf`-equivalent entry.
3. **Persistence**: Writes modifications back to `~/.superfile/config.json` immediately when users add or remove pins, ensuring state consistency without application restart.

This approach treats pinned directories as first-class navigation citizens while maintaining complete separation from the static documentation structure defined in [`navigation.ts`](https://github.com/yorukot/superfile/blob/main/navigation.ts).

## Implementation Examples

### Rendering the Complete Sidebar

The following React/TypeScript pattern demonstrates how Superfile composes the static navigation tree with dynamic pinned content:

```tsx
import { navigation, flattenNav } from '@/lib/navigation';

function Sidebar() {
  const staticItems = navigation.map(node =>
    isGroup(node) ? (
      <Collapsible key={node.label} label={node.label}>
        {node.items.map(item => <Link key={item.slug} to={item.slug}>{item.label}</Link>)}
      </Collapsible>
    ) : (
      <Link key={node.slug} to={node.slug}>{node.label}</Link>
    )
  );

  const pinned = usePinnedDirectories(); // reads ~/.superfile/config.json
  const pinnedItems = pinned.map(dir => (
    <Link key={dir} to={`pinned/${encodeURIComponent(dir)}`}>{path.basename(dir)}</Link>
  ));

  return (
    <nav>
      <Section title="Pinned">{pinnedItems}</Section>
      <Section title="Docs">{staticItems}</Section>
    </nav>
  );
}

```

### Managing Pinned Directories

The following utility functions demonstrate the file system operations for modifying the pinned list:

```typescript
import fs from 'fs';
import os from 'os';
import path from 'path';

const CONFIG_PATH = path.join(os.homedir(), '.superfile', 'config.json');

export function addPin(dir: string) {
  const cfg = JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf-8'));
  cfg.pinned = Array.from(new Set([...(cfg.pinned || []), dir])); // avoid duplicates
  fs.writeFileSync(CONFIG_PATH, JSON.stringify(cfg, null, 2));
}

```

### Sequential Navigation Implementation

To implement documentation pagination using the navigation utilities:

```typescript
import { getPrevNext } from '@/lib/navigation';

function DocNav({ slug }: { slug: string }) {
  const { prev, next } = getPrevNext(slug);
  return (
    <div className="doc-nav">
      {prev && <Link to={prev.slug}>← {prev.label}</Link>}
      {next && <Link to={next.slug}>{next.label} →</Link>}
    </div>
  );
}

```

## Summary

- **Static Architecture**: The sidebar structure is defined declaratively in [`website/src/lib/navigation.ts`](https://github.com/yorukot/superfile/blob/main/website/src/lib/navigation.ts) using the `NavLeaf` and `NavGroup` interfaces, providing type-safe, immutable navigation hierarchies.
- **Dynamic Pinned Directories**: User-specific shortcuts are stored in `~/.superfile/config.json` and rendered as a distinct "Pinned" section, allowing runtime customization without source modification.
- **Navigation Utilities**: Helper functions `flattenNav()` and `getPrevNext()` enable efficient tree traversal and sequential navigation generation for documentation workflows.
- **Separation of Concerns**: The architecture cleanly separates immutable application structure from mutable user preferences, enabling independent updates to either component.

## Frequently Asked Questions

### How does Superfile differentiate between static documentation links and user-pinned directories?

Superfile maintains static documentation links in the TypeScript source file [`website/src/lib/navigation.ts`](https://github.com/yorukot/superfile/blob/main/website/src/lib/navigation.ts), while user-pinned directories reside in the runtime configuration file `~/.superfile/config.json`. The rendering layer combines both sources during component initialization, displaying pinned items in a dedicated section above the static navigation tree.

### What file contains the sidebar navigation structure in Superfile?

The immutable sidebar structure is defined in [`website/src/lib/navigation.ts`](https://github.com/yorukot/superfile/blob/main/website/src/lib/navigation.ts), which exports the `navigation` constant and related TypeScript interfaces (`NavLeaf`, `NavGroup`). This file serves as the single source of truth for static navigation elements across the application.

### How does the `getPrevNext` function determine documentation pagination?

The `getPrevNext(slug)` function first calls `flattenNav()` to generate a one-dimensional array of navigation leaves in declaration order, then performs an index lookup on the provided slug. It returns objects containing the `label` and `slug` properties for the entries immediately preceding and following the current page, or null values when at the boundaries of the navigation sequence.

### Can pinned directories be modified without restarting Superfile?

Yes, the pinned directory configuration is read from `~/.superfile/config.json` at startup and written back immediately upon modification. Changes take effect in the sidebar without requiring application restart, as the UI layer references the current state of the configuration file when rendering the navigation components.