UI Component Library
Relevant source files
The following files were used as context for generating this wiki page:The Umami application's user interface is constructed using a combination of a foundational third-party component library and a set of custom, application-specific components. The core of the UI is built upon @umami/react-zen, which provides fundamental building blocks like buttons, forms, and layout primitives. On top of this, the project defines its own specialized components for displaying metrics, handling user input, and rendering complex data visualizations like charts and maps.
This component architecture promotes consistency and reusability across the application. Components are organized by function into directories such as common, input, metrics, and charts. A central export file, src/index.ts, aggregates these components, making them easily accessible throughout the application. This modular approach allows for clear separation of concerns, with generic layout components in common, interactive elements in input, and data-heavy displays in metrics and charts.
Sources: package.json:44, src/index.ts:43-85, src/app/layout.tsx:9
Core Dependencies
The UI component system relies on several key npm packages.
| Package | Version | Description |
|---|---|---|
@umami/react-zen | ^0.211.0 | The primary component library providing foundational UI elements like Button, Form, Grid, and Column. |
react | ^19.2.3 | The core JavaScript library for building the user interface. |
chart.js | ^4.5.1 | A powerful charting library used as the basis for all data visualizations. |
lucide-react | ^0.543.0 | Provides a set of icons used alongside custom SVG icons. |
classnames | ^2.3.1 | A utility for conditionally joining CSS class names together. |
react-simple-maps | ^2.3.0 | Used for rendering the world map visualization on the dashboard. |
This diagram shows the dependency relationship between application pages, custom components, and the base libraries.
Component Categories
Components are organized into several distinct categories based on their functionality. The main entry point src/index.ts exports a wide array of these components for consumption by different pages.
Sources: src/index.ts:43-85
Common Components
These components are used for structuring page layouts and providing consistent UI patterns across the application. They form the basic scaffolding for most pages.
| Component | Description | Example Usage File |
|---|---|---|
PageBody | A main container for page content. | src/app/(main)/links/LinksPage.tsx:13 |
PageHeader | Displays the title of a page and can contain action buttons. | src/app/(main)/console/[websiteId]/TestConsolePage.tsx:109 |
Panel | A bordered container used to group related content, such as charts or tables. | src/app/(main)/websites/[websiteId]/WebsitePanels.tsx:13 |
SideMenu | A vertical navigation menu, used in the website-specific navigation. | src/app/(main)/websites/[websiteId]/WebsiteNav.tsx:149 |
LoadingPanel | A wrapper that displays a loading state while data is being fetched. | src/app/(main)/websites/[websiteId]/(reports)/utm/UTM.tsx:23 |
GridRow | A layout component for arranging panels and other elements in a grid. | src/app/(main)/websites/[websiteId]/WebsitePanels.tsx:20 |
The following diagram illustrates how a typical page is composed using these common components.
Input Components
This category includes components designed for user interaction, such as forms, buttons, and selection controls. They are built upon primitives from @umami/react-zen.
| Component | Description | Example Usage File |
|---|---|---|
Form | A wrapper for form elements that handles submission and error states. | src/app/(main)/links/LinkEditForm.tsx:49 |
FormField | A component that wraps an input field with a label and validation rules. | src/app/(main)/links/LinkEditForm.tsx:51 |
TextField | A standard text input field. | src/app/(main)/links/LinkEditForm.tsx:55 |
Button | A standard button, often used for actions or submitting forms. | src/app/(main)/console/[websiteId]/TestConsolePage.tsx:149 |
DialogButton | A button that opens a dialog window when clicked. | src/index.ts:72 |
WebsiteSelect | A specialized dropdown for selecting a website. | src/app/(main)/websites/[websiteId]/WebsiteNav.tsx:142 |
FormSubmitButton | A dedicated submit button for a Form, which automatically handles the pending state. | src/app/(main)/links/LinkEditForm.tsx:100 |
The LinkEditForm provides a clear example of how these input components are combined to create a data entry form.
// src/app/(main)/links/LinkEditForm.tsx:49-56
<Form onSubmit={handleSubmit} error={getErrorMessage(error)} defaultValues={{ slug, ...data }}>
<FormField
label={formatMessage(labels.name)}
name="name"
rules={{ required: formatMessage(labels.required) }}
>
<TextField autoComplete="off" autoFocus />
</FormField>
</Form>
Sources: src/app/(main)/links/LinkEditForm.tsx:49-103, src/index.ts:71-78
Charting Components
Charting components are responsible for all data visualization. They are built using chart.js and are wrapped in custom React components to handle data fetching and configuration.
Chart.tsx: This is likely a base wrapper component, but the provided file list does not contain its source.BarChart.tsx: A component for rendering bar charts. It is used by more specific chart components.PieChart.tsx: A component for rendering pie and doughnut charts, used in the UTM report.PageviewsChart.tsx: A specialized bar chart that displays pageviews and sessions over time. It acceptsdata,unit,minDate, andmaxDateas props. It internally configures twobardatasets for visitors and views, and can optionally display twolinedatasets for comparison data.
The rendering flow for the PageviewsChart is as follows:
Metrics Components
These components are designed to display analytics data in various formats, such as tables and cards.
MetricsTable: A versatile table used to display lists of metrics like top pages, referrers, browsers, and locations. It is configured via atypeprop (path,referrer,browser, etc.).ListTable: A simpler table for displaying a label, count, and percentage, often used alongside aPieChart.EventsChart: A chart specifically for visualizing event data over time.WorldMap: Renders a geographical map highlighting visitor locations.
The WebsitePanels component demonstrates how MetricsTable is used within a tabbed interface to show different slices of data.
// src/app/(main)/websites/[websiteId]/WebsitePanels.tsx:26-32
<Tabs>
<TabList>
<Tab id="path">{formatMessage(labels.path)}</Tab>
<Tab id="entry">{formatMessage(labels.entry)}</Tab>
<Tab id="exit">{formatMessage(labels.exit)}</Tab>
</TabList>
<TabPanel id="path">
<MetricsTable type="path" title={formatMessage(labels.path)} {...tableProps} />
</TabPanel>
</Tabs>
Sources: src/app/(main)/websites/[websiteId]/WebsitePanels.tsx:1-114, src/index.ts:79-85
SVG Icons
The application uses a large set of custom SVG icons, which are managed and exported from a central index file. A script build-icons in package.json uses svgr to convert SVG files from src/assets into React components.
A few examples of available icons include:
BarChartBoltDashboardFunnelLightningLocationMoneyNetworkTargetVisitorWebsite
These icons are then used throughout the application, for example in the WebsiteNav component to decorate menu items.
Sources: src/components/svg/index.ts:1-37, package.json:20, src/app/(main)/websites/[websiteId]/WebsiteNav.tsx:8-15
Conclusion
The UI component library in Umami is a well-structured system that leverages the robust @umami/react-zen library for its foundation while providing a rich set of custom, domain-specific components. This layered approach enables rapid development of new features with a consistent look and feel. The clear separation of components into categories like common, input, metrics, and charts ensures maintainability and scalability of the frontend codebase. The centralized export strategy and automated icon generation further streamline the development process.