Menu

Web Application Architecture

Relevant source files

Purpose and Scope

This document details the architecture of RAGFlow's web application, covering the Umi framework configuration, routing system, styling infrastructure (Tailwind CSS with Ant Design), and build pipeline. For internationalization details, see Internationalization System. For specific UI implementations, see Knowledge Base and Chat Interface and Agent Flow Builder Interface.

Technology Stack Overview

The RAGFlow web application is built on the following core technologies:

TechnologyVersionPurpose
React^18.2.0UI framework
Umi^4.0.90Enterprise-level React framework
TypeScript^5.0.3Type safety
Tailwind CSS^3Utility-first CSS framework
Ant Design^5.12.7Component library
Vite (via Umi)-Build tool and dev server

Additional key libraries include:

  • State Management: zustand (^4.5.2)
  • Data Fetching: @tanstack/react-query (^5.40.0), axios (^1.12.0)
  • Routing: Built into Umi framework
  • Styling Utilities: class-variance-authority (^0.7.0), clsx (^2.1.1), tailwind-merge (^2.5.4)
  • UI Components: @radix-ui/* primitives, @ant-design/pro-components (^2.6.46)

Sources: web/package.json1-172

Umi Framework Configuration

Framework Overview

The web application uses UmiJS v4.0.90 as its React framework, providing routing, build tooling, and plugin architecture. UmiJS wraps Webpack and provides conventions for enterprise applications.

Diagram: Umi Framework Architecture with Code Entities

Sources: web/.umirc.ts1-76 web/package.json4-15 web/package.json114

Core Configuration File Structure

The .umirc.ts configuration file exports a defineConfig() object with the following structure:

Table: Key Configuration Properties

PropertyValuePurposeLine Reference
titleappName (from conf.json)Application title in browser tabweb/.umirc.ts9
outputPath'dist'Build output directoryweb/.umirc.ts10
alias{ '@parent': path.resolve(__dirname, '../') }Path alias for importsweb/.umirc.ts11
npmClient'npm'Package managerweb/.umirc.ts12
routesimported from ./src/routesRoute configurationweb/.umirc.ts14
hashtrueFilename hashing for cache bustingweb/.umirc.ts18
favicons['/logo.svg']Favicon configurationweb/.umirc.ts19
history.type'browser'HTML5 History API routingweb/.umirc.ts22-24
jsMinifier'none'Disabled to fix Lexical library issueweb/.umirc.ts29
devtool'source-map'Debug source mapsweb/.umirc.ts35

Plugins Configuration:

Less Loader Configuration:

The Less loader injects global styles via a hack that imports the main Less file into all Less modules:

This allows access to variables and mixins defined in src/less/index.less across all component Less files.

Copy Operations:

Development Proxy Configuration:

The proxy routes backend API calls during development:

Sources: web/.umirc.ts8-76

Webpack Chain Customization

The chainWebpack(memo, args) function extends Umi's webpack configuration:

Diagram: Webpack Chain Modifications

Markdown Loader:

Markdown files are loaded as raw text sources:

This allows importing .md files as strings for rendering in documentation components.

TerserPlugin Configuration:

TerserPlugin is explicitly added to handle Lexical library minification, which fails with the default esbuild minifier:

Note: The main jsMinifier is set to 'none' web/.umirc.ts29 but TerserPlugin is still used for specific optimization needs.

ESLint Plugin (Currently Disabled):

The ESLint webpack plugin configuration is commented out but shows the pattern for adding linting during build:

Sources: web/.umirc.ts58-73 web/.umirc.ts2

Routing Architecture

Route Structure and Routes Enum

The application defines all routes in an enum Routes exported from web/src/routes.ts. This enum provides type-safe route constants used throughout the application.

Diagram: Routes Enum Structure and Composition

Key Route Patterns:

  1. Composed Routes: Many routes are built by concatenating base paths:

  2. Dynamic Segments: Routes with :id parameters are composed at usage:

Sources: web/src/routes.ts3-59

UmiJS Route Configuration

Routes are configured as an array of route objects in web/src/routes.ts and imported into .umirc.ts:

Diagram: Route Configuration Structure

Route Configuration Examples:

1. Public Route (no authentication):

2. Authenticated Route (with wrapper):

3. Nested Dataset Routes (lines 200-231):

4. Admin Routes with Enterprise Guard (lines 351-398):

The IS_ENTERPRISE constant (imported from @/pages/admin/utils) conditionally includes enterprise-specific routes at build time.

Sources: web/src/routes.ts61-401 web/src/routes.ts1 web/.umirc.ts14 web/.umirc.ts22-24

The application centralizes navigation logic in useNavigatePage() hook, which provides type-safe navigation functions:

Diagram: useNavigatePage Hook Structure

Usage in Components:

Key Pattern: Most navigation functions return higher-order functions (id) => () => navigate(...) to enable direct use as onClick handlers without creating inline functions.

Sources: web/src/hooks/logic-hooks/navigate-hooks.ts12-200 web/src/pages/home/datasets.tsx26 web/src/pages/datasets/dataset-card.tsx20

Page Component File Organization

Pages follow a consistent structure:

src/pages/
├── home/
│   ├── index.tsx          # Main page component
│   ├── banner.tsx         # NextBanner component
│   ├── datasets.tsx       # Datasets section component
│   ├── applications.tsx   # Applications section component
│   ├── chat-list.tsx      # ChatList component
│   ├── search-list.tsx    # SearchList component
│   └── agent-list.tsx     # Agents component
├── datasets/
│   ├── dataset-card.tsx   # DatasetCard component
│   ├── dataset-dropdown.tsx
│   └── use-rename-dataset.ts  # Custom hook
├── next-chats/
│   ├── index.tsx
│   └── chat/
│       └── index.tsx      # Chat session page
├── agents/
│   ├── index.tsx
│   ├── agent-log-page/
│   └── agent-templates/
└── admin/
    ├── layouts/
    │   ├── root-layout.tsx
    │   └── navigation-layout.tsx
    ├── wrappers/
    │   └── authorized.tsx
    └── users/
        └── index.tsx

Sources: web/src/pages/home/index.tsx1-17 web/src/pages/home/banner.tsx1-53 web/src/pages/home/datasets.tsx1-80 web/src/pages/datasets/dataset-card.tsx1-56

Styling System Architecture

Three-Layer Styling Approach

Sources: web/tailwind.css1-311 web/tailwind.config.js1-215

CSS Variable System

The tailwind.css file defines a comprehensive set of CSS custom properties for theming. The application uses a dual-theme system with :root for light mode and .dark selector for dark mode.

Diagram: CSS Variable Organization

Key Variable Categories:

1. Core Layout Variables (:root lines 6-69):

2. Design System Variables (:root lines 70-135):

3. State Colors (:root lines 119-124):

4. Team/Role Colors (:root lines 125-130):

Dark Theme (.dark selector, lines 137-253):

The dark theme overrides all variables with dark equivalents:

Custom Utilities (@layer utilities, lines 289-322):

The .scrollbar-auto utility provides custom scrollbar styling:

Sources: web/tailwind.css5-254 web/tailwind.css289-322

Tailwind Configuration

The tailwind.config.js file extends Tailwind's default theme with custom design tokens that map to the CSS variables defined in tailwind.css.

Table: Core Configuration Properties

PropertyValuePurposeLine Reference
darkMode['selector']Class-based dark mode with .darkweb/tailwind.config.js6
content['./src/pages/**/*.tsx', ...]Files to scan for classesweb/tailwind.config.js7-11
theme.container.centertrueCenter containersweb/tailwind.config.js14
theme.container.padding'2rem'Container paddingweb/tailwind.config.js15

Custom Screens (Responsive Breakpoints):

Custom Color Mappings:

The configuration maps over 50 custom color tokens to CSS variables. Key patterns:

1. Simple Variable Mapping:

2. Alpha-Capable Colors (using RGB space-separated values):

This enables opacity utilities like text-primary/50 (50% opacity).

3. Predefined Opacity Variants:

Custom Animations:

Plugins:

Border Width Extension:

Sources: web/tailwind.config.js5-227

Component Styling Pattern with CVA

Components use class-variance-authority (CVA) for type-safe variant management. This pattern combines base styles with configurable variants.

Diagram: CVA Component Pattern

Button Component Implementation (web/src/components/ui/button.tsx):

1. CVA Definition (lines 8-70):

2. Component Interface (lines 72-78):

VariantProps<typeof buttonVariants> provides TypeScript inference for variant and size props.

3. Component Implementation (lines 80-113):

Key Features:

  1. Slot Pattern: Uses @radix-ui/react-slot for composition when asChild={true}
  2. cn() Utility: Merges classes with tailwind-merge to resolve conflicts
  3. Loading State: Shows spinner and disables button when loading={true}
  4. Block Variant: Conditional class for full-width buttons

Badge Component Example (web/src/components/ui/badge.tsx):

A simpler CVA pattern:

Sources: web/src/components/ui/button.tsx8-122 web/src/components/ui/badge.tsx6-38 web/package.json68

Ant Design Integration

Ant Design components are used alongside custom components:

Component TypeLibraryUsage
Forms, ModalsAnt DesignHigh-level business components
Primitives (Dropdown, Dialog)Radix UIAccessible base components
Custom UI (Button, Card)Custom + CVABrand-specific styling

Sources: web/package.json22-24 web/package.json31-56

Build and Development Pipeline

NPM Scripts and Workflow

Diagram: Development and Build Pipeline

Sources: web/package.json4-20 web/.umirc.ts40-56

NPM Scripts Reference

Table: Complete Script Definitions

ScriptCommandPurposeLine Reference
devcross-env UMI_DEV_SERVER_COMPRESS=none umi devStart dev server without compressionweb/package.json7
startnpm run devAlias for dev scriptweb/package.json12
buildumi buildProduction buildweb/package.json5
postinstallumi setupUmi framework setupweb/package.json8
setupumi setupManual setup triggerweb/package.json11
lintumi lint --eslint-onlyESLint code checkingweb/package.json9
testjest --no-cache --coverageJest unit tests with coverageweb/package.json14
build-storybookstorybook buildBuild Storybook docsweb/package.json6
storybookstorybook dev -p 6006Run Storybook dev serverweb/package.json13
preparecd .. && husky web/.huskyInitialize Husky git hooksweb/package.json10

Development Server Configuration:

The cross-env UMI_DEV_SERVER_COMPRESS=none prefix disables compression for better debugging and faster development iteration.

Sources: web/package.json4-14

Lint-Staged Configuration

Git pre-commit hooks format code automatically:

Sources: web/package.json16-20

Build Optimizations

  1. Hash-based Caching: hash: true enables content-based cache busting web/.umirc.ts18
  2. Source Maps: devtool: 'source-map' for debugging web/.umirc.ts35
  3. Terser Minification: Explicitly configured to handle Lexical library web/.umirc.ts54
  4. esbuildMinifyIIFE: Additional optimization layer web/.umirc.ts16

Sources: web/.umirc.ts16-35

Component Architecture Patterns

Page Component Architecture Pattern

Page components follow a consistent three-layer architecture using custom hooks, TanStack Query, and component composition.

Diagram: Datasets Page Component Structure

useFetchNextKnowledgeListByPage Hook Pattern:

This custom hook wraps TanStack Query's useInfiniteQuery to provide paginated data fetching:

DatasetCard Component (lines 16-40 in dataset-card.tsx):

Key Patterns:

  1. Custom Hook Composition: Page components are thin wrappers that compose multiple hooks
  2. Loading States: Conditional rendering based on loading from React Query
  3. Empty States: <EmptyAppCard> with type-based content and action buttons
  4. Contextual Navigation: Navigation callbacks include context like isCreate: true for onboarding flows
  5. Modal State: Extracted into custom hooks (useRenameDataset) for reusability

Component Communication Pattern:

Sources: web/src/pages/home/datasets.tsx14-79 web/src/pages/datasets/dataset-card.tsx16-40 web/src/hooks/use-knowledge-request.ts (referenced)

Home Page Component Architecture

Diagram: Home Page Component Composition

Component Interaction Pattern:

The home page demonstrates a consistent pattern used throughout the application:

  1. Data Fetching: useFetchNextKnowledgeListByPage() hook provides { kbs, loading }
  2. Conditional Rendering: Show <CardSkeleton /> during loading, <EmptyAppCard /> when empty
  3. Card Grid: Use <CardSineLineContainer> for responsive grid layout
  4. Navigation: Use navigateToDatasetList({ isCreate: boolean }) for contextual navigation

Key Code Entities:

  • <HomeIcon>: Custom SVG icon component from @/components/svg-icon
  • <CardSineLineContainer>: Responsive flex container for card grids
  • <EmptyAppCard>: Empty state with call-to-action button
  • EmptyCardType enum: Defines different empty state variants
  • IconMap: Maps Routes enum values to icon names

Sources: web/src/pages/home/index.tsx5-17 web/src/pages/home/banner.tsx42-52 web/src/pages/home/datasets.tsx14-79 web/src/pages/home/applications.tsx27-114

Custom UI Component Pattern with CVA

The application uses a consistent pattern for custom UI components, combining Radix UI primitives, class-variance-authority (CVA), and Tailwind CSS:

Diagram: UI Component Architecture Pattern

Button Component Implementation Details:

1. Type-Safe Props with CVA (lines 77-83):

VariantProps<typeof buttonVariants> provides TypeScript inference for variant and size props, enabling autocomplete and type checking.

2. Radix Slot Pattern (lines 100):

When asChild={true}, the component renders its child as the interactive element (composition pattern from Radix UI).

3. cn() Utility for Class Merging (lines 104-108):

The cn() function (from @/lib/utils) uses tailwind-merge to intelligently merge Tailwind classes, resolving conflicts (e.g., bg-red-500 + bg-blue-500bg-blue-500).

4. Loading State Handling (lines 110, 113):

Segmented Control Component

The <Segmented> component demonstrates a different pattern - a custom selection control without a Radix primitive:

Usage Example (from applications.tsx:45-77):

The component renders a button group where one option is always selected (radio button behavior), styled with Tailwind classes and custom active state classes.

Sources: web/src/components/ui/button.tsx8-118 web/src/pages/home/applications.tsx45-77

Integration with Backend

API Proxy Configuration

Development proxy routes API calls to backend server:

This enables:

  • Seamless development without CORS issues
  • WebSocket connections for streaming responses
  • Consistent API paths between dev and production

Sources: web/.umirc.ts40-49

Data Fetching Pattern

The application uses TanStack Query (React Query) for data fetching:

Example: Infinite scroll data fetching

Sources: web/src/pages/knowledge/index.tsx33-40 web/package.json58-59 web/package.json65

State Management Strategy

The application uses a minimal state management approach:

  1. Server State: TanStack Query for API data
  2. Local State: React useState, useMemo for component state
  3. Global State: Zustand for cross-component state (auth, theme, etc.)

This avoids complex Redux setup while maintaining clean data flow.

Sources: web/package.json116

Asset Management

Static Assets

Static assets are managed through multiple mechanisms:

Favicon and Icons:

Sources: web/.umirc.ts19-20 web/.umirc.ts36-39

Icon System

The application uses multiple icon approaches:

  1. Ant Design Icons: @ant-design/icons for standard icons
  2. Lucide React: lucide-react for additional icons
  3. Custom IconFont: SVG sprite loaded via iconfont.js

Sources: web/package.json22 web/package.json82 web/.umirc.ts20

Development Tools

Click-to-Component

React Dev Inspector plugin enables clicking components to open in editor:

Sources: web/.umirc.ts25-28

TypeScript Configuration

The application uses TypeScript with strict configuration:

  • Engine requirement: node >= 18.20.4
  • TypeScript version: ^5.0.3

Sources: web/package.json166-168 web/package.json163

Testing Setup

Jest is configured with jsdom environment for component testing:

  • Framework: Jest ^29.7.0
  • Testing Library: @testing-library/react ^15.0.7
  • Environment: jest-environment-jsdom

Sources: web/package.json136-137 web/package.json114-115 web/package.json150