Last updated: Sep 1, 2025, 01:10 PM UTC

SPA Navigation Implementation Guide

Overview

This document provides a comprehensive guide to the Single Page Application (SPA) navigation system implemented for Sasha Studio's documentation viewer. The system generates content-only HTML files and provides seamless navigation without full page reloads.

Architecture

SPA Navigation Components

graph TD A[docs-viewer.html] --> B[docs-router.js] B --> C[Navigation API (/api/navigation)] B --> D[Content Files (/content/*.html)] C --> E[Markdown Files Scan] D --> F[Content-Only HTML] E --> G[Navigation Tree] F --> H[Dynamic Loading] G --> I[Sidebar Navigation] H --> I

File Structure

/home/nodejs/all-project-files/
β”œβ”€β”€ docs/                    # Markdown source files
β”‚   β”œβ”€β”€ getting-started/
β”‚   β”œβ”€β”€ guides/
β”‚   └── ...
β”œβ”€β”€ html-static/
β”‚   β”œβ”€β”€ content/            # Generated content-only HTML
β”‚   β”‚   β”œβ”€β”€ getting-started/
β”‚   β”‚   β”œβ”€β”€ guides/
β”‚   β”‚   └── ...
β”‚   β”œβ”€β”€ docs-viewer.html    # SPA shell application
β”‚   β”œβ”€β”€ js/
β”‚   β”‚   β”œβ”€β”€ docs-router.js  # Client-side routing
β”‚   β”‚   └── main.js
β”‚   └── css/
β”‚       └── notion-style.css

Implementation Details

1. Content-Only HTML Generation

Purpose: Generate minimal HTML files optimized for SPA loading.

Script: scripts/generate-spa-html.js

Key Features:

  • Scans markdown files recursively
  • Generates content-only HTML (no navigation embedded)
  • Handles emoji replacement and syntax highlighting
  • Maintains proper document metadata

Generated HTML Structure:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="doc-path" content="guides/quick-start.html">
    <meta name="doc-title" content="Quick Start Guide">
</head>
<body>
    <article class="article">
        <header class="article-header">
            <h1 class="article-title">Quick Start Guide</h1>
        </header>
        <div class="article-content">
            <!-- Processed markdown content -->
        </div>
    </article>
</body>
</html>

2. Navigation API

Endpoint: /api/navigation

Purpose: Dynamically build navigation tree from markdown files

Response Format:

{
  "navigation": {
    "name": "Documentation",
    "children": [
      {
        "name": "Getting Started",
        "children": [],
        "files": [
          {
            "name": "quick-start.md",
            "title": "Quick Start Guide",
            "urlPath": "getting-started/quick-start.html"
          }
        ]
      }
    ]
  },
  "totalDocuments": 25,
  "lastUpdated": "2025-08-24T09:00:00.000Z"
}

3. SPA Shell (docs-viewer.html)

Purpose: Main application shell with fixed sidebar and dynamic content area

Key Components:

  • Fixed sidebar with search functionality
  • Dynamic content loading area
  • Breadcrumb navigation
  • Loading states and error handling

Features:

  • Hash-based routing (#/path/to/document)
  • Search filtering of navigation
  • Responsive design
  • Print/PDF export functionality

4. Client-Side Router (docs-router.js)

Class: DocsRouter

Key Methods:

class DocsRouter {
  async init()                    // Initialize router and load navigation
  async loadNavigation()          // Fetch navigation from API
  async navigateToPath(path)      // Load content for specific path
  renderNavigationTree(node)      // Build navigation HTML
  filterNavigation(query)         // Search functionality
  updateBreadcrumbs(path)         // Update breadcrumb trail
}

Navigation Flow:

  1. Initialize router on page load
  2. Load navigation tree from API
  3. Render sidebar navigation
  4. Listen for hash changes and navigation clicks
  5. Load content dynamically via fetch
  6. Update breadcrumbs and active states

Docker Integration

Container Startup Process

  1. Copy Phase: Copy markdown files to persistent volume

    cp -r "/app/deployed-md-files/docs" "/home/nodejs/all-project-files/"
    
  2. SPA Generation: Generate content-only HTML files

    node /app/scripts/generate-spa-html.js
    
  3. Asset Copy: Copy SPA shell and assets

    cp /app/html-static/docs-viewer.html /home/nodejs/all-project-files/html-static/
    cp -r /app/html-static/js /home/nodejs/all-project-files/html-static/
    cp -r /app/html-static/css /home/nodejs/all-project-files/html-static/
    
  4. Background Generation: Generate full HTML for iframe viewing

    (sleep 10 && node /app/scripts/generate-initial-html.js) &
    

Dockerfile Changes

Eliminated:

  • doc-builder stage
  • Pre-built HTML copying
  • Complex build pipeline

Added:

  • Direct markdown copying
  • SPA asset inclusion
  • Generation scripts
# Copy only what's needed
COPY --chown=nodejs:nodejs deployed-md-files/docs /app/deployed-md-files/docs
COPY --chown=nodejs:nodejs claudecodeui/html-static/docs-viewer.html /app/html-static/docs-viewer.html
COPY --chown=nodejs:nodejs claudecodeui/html-static/css /app/html-static/css
COPY --chown=nodejs:nodejs claudecodeui/html-static/js /app/html-static/js
COPY --chown=nodejs:nodejs claudecodeui/scripts ./scripts

Development Workflow

Local Development

  1. Start Server: npm run dev (port 3007)
  2. Edit Markdown: Modify files in deployed-md-files/docs/
  3. Generate HTML: Click "Publish HTML" in UI
  4. Auto-Refresh: DocsPanel refreshes automatically via WebSocket

Adding New Documentation

  1. Create Markdown: Add .md file to appropriate directory
  2. Generate Content:
    • Automatic: On next container restart
    • Manual: Click "Publish HTML" button
  3. Navigation Update: Navigation API reflects changes immediately

Customizing Navigation

Search Functionality:

filterNavigation(query) {
  // Filters navigation tree based on search query
  // Supports title and filename matching
  // Maintains hierarchical structure
}

Custom Styling:

  • Modify css/notion-style.css for content styling
  • Update docs-viewer.html for shell styling
  • Navigation styles in main CSS file

Performance Considerations

Optimization Features

  • Lazy Loading: Content loaded only when requested
  • Caching: Browser caches content files with cache-busting
  • Minimal HTML: Content-only files reduce transfer size
  • Tree Shaking: Navigation API returns only needed structure

Scalability

  • Large Document Sets: Navigation API handles hundreds of documents
  • Memory Efficiency: Client-side routing avoids full page reloads
  • Search Performance: Filtering happens client-side for instant results

Troubleshooting

Common Issues

Navigation Not Loading:

# Check if navigation API responds
curl http://localhost:3005/api/navigation

Content Not Found:

# Verify content files exist
ls -la /home/nodejs/all-project-files/html-static/content/

SPA Shell Not Loading:

# Check if docs-viewer.html exists
ls -la /home/nodejs/all-project-files/html-static/docs-viewer.html

Debug Mode

Enable detailed logging:

// In docs-router.js
console.log('πŸ” Debug: Navigation loaded', navigation);
console.log('πŸ” Debug: Loading content', path);

Future Enhancements

Potential Improvements

  1. Full-Text Search: Index content for comprehensive search
  2. Bookmarking: Support for deep-linking to sections
  3. Print Optimization: Better print styles for documentation
  4. Offline Support: Service worker for offline access
  5. Analytics: Track popular documentation sections

API Enhancements

  1. Pagination: For very large document sets
  2. Metadata: Additional file information (modified date, author)
  3. Tags/Categories: Enhanced organization
  4. Search API: Server-side full-text search

Status: Complete
Generated: 2025-08-24 09:00 UTC