How Reusable UI Components Are Structured in Open-SEO: A React and TypeScript Architecture Guide
Open-SEO organizes its reusable UI components into a layered React and TypeScript architecture that separates core design primitives from feature-specific implementations and marketing-site views.
The open-seo repository implements a clear component hierarchy designed for maximum reusability across its internal dashboard and public-facing marketing site. Built with React and TypeScript, the codebase uses Tailwind CSS and DaisyUI for styling, ensuring consistent theming while maintaining strict separation between generic UI primitives and domain-specific feature components.
Project Structure and Component Hierarchy
The repository divides its React components into three distinct layers based on responsibility and reuse patterns.
Core Components Directory
The src/client/components/ directory contains the foundational building blocks used throughout the internal dashboard. These are small, self-contained functional components that accept props for customization, such as className, maxWidth, and callback handlers.
Key files in this layer include:
src/client/components/Modal.tsx– A generic modal wrapper with escape-key handlingsrc/client/components/Sidebar.tsx– The navigation sidebar used across the dashboardsrc/client/components/table/AppDataTable.tsx– A compound table component with pagination and sorting
These components export single React functions with explicit TypeScript interfaces, making imports predictable and type-safe.
Feature-Specific UI Layer
The src/client/features/ directory houses domain-specific implementations that compose core components into complete user interfaces. Each feature (keywords, domains, AI-search) maintains its own folder structure, isolating business logic while reusing the shared visual language.
For example, src/client/features/keywords/components/KeywordUi.tsx demonstrates how feature developers combine AppDataTable, Sidebar, and custom card components without duplicating core UI code.
Marketing Site Components
The web/src/components/ directory contains UI pieces specific to the public-facing marketing site, such as landing pages and documentation. While these components remain reusable within the marketing context, they are organized separately from the dashboard UI to accommodate different design requirements and audience needs.
Notable files include web/src/components/site-footer.tsx and web/src/components/landing-page.tsx.
Component Design Patterns
Open-SEO employs several React patterns to maximize component flexibility and maintainability.
Simple Functional Components
The codebase favors stateless functional components that receive props and return JSX. This pattern appears in src/client/components/Modal.tsx, where the component accepts configuration through props rather than maintaining internal state for visibility or content.
Compound Component Architecture
Complex UI elements like data tables use compound component patterns. The AppDataTable.tsx file implements this by providing a parent component that supplies context and layout, while child parts (headers, body rows, pagination) are configured via props or composition slots.
Tailwind-Driven Styling
Components embed Tailwind utility classes directly in their markup rather than relying on external CSS files. This approach, visible in web/src/components/site-footer.tsx, enables responsive design and easy theming through DaisyUI utility conventions while keeping the component footprint minimal.
Reusability Mechanics and Type Safety
Open-SEO ensures component reusability through several technical mechanisms.
Prop-Driven Customization – Most components expose a standardized prop interface including className for style overrides and event callbacks for behavior customization. This allows callers to tailor appearance without forking component code.
Shared Type Definitions – Types such as LinkOptions from TanStack Router and table meta interfaces are defined once and imported across the component tree. This centralized type management prevents drift between related components.
Consistent Naming Conventions – Files export components whose names match their filenames exactly (e.g., Modal from Modal.tsx). This one-to-one mapping simplifies imports and IDE autocomplete functionality.
Feature-Level Composition – Rather than creating monolithic feature components, the architecture encourages composing small core pieces. A keyword management interface might import Button, Modal, and AppDataTable from the core directory, then wire them together with feature-specific data handlers.
Practical Implementation Example
The following Button component from src/client/components/Button.tsx illustrates the reusability pattern:
// src/client/components/Button.tsx
import type { ReactNode } from "react";
export function Button({
children,
onClick,
className = "",
type = "button",
}: {
children: ReactNode;
onClick?: () => void;
className?: string;
type?: "button" | "submit" | "reset";
}) {
return (
<button
type={type}
onClick={onClick}
className={`btn ${className}`}
>
{children}
</button>
);
}
This component can be imported into any feature or marketing page:
import { Button } from "@/client/components/Button";
function ExportPanel() {
return (
<div className="p-4">
<Button
className="btn-primary"
onClick={() => console.log("export")}
>
Export to CSV
</Button>
</div>
);
}
Summary
- Open-SEO structures reusable UI components across three directories:
src/client/components/for core primitives,src/client/features/for domain-specific compositions, andweb/src/components/for marketing-site UI. - Core components like
Modal.tsxandSidebar.tsxare built as simple functional components with explicit TypeScript interfaces, accepting props for customization rather than managing complex internal state. - Compound component patterns appear in complex elements such as
AppDataTable.tsx, enabling flexible table configurations through composition. - Tailwind CSS and DaisyUI provide the styling foundation, with utility classes embedded directly in component markup for theme consistency and responsive behavior.
- Type safety is maintained through shared interfaces and TanStack Router types, while strict naming conventions ensure predictable imports across the codebase.
Frequently Asked Questions
What technology stack supports the reusable UI components in open-seo?
Open-SEO uses React with TypeScript for component logic, Tailwind CSS with DaisyUI for styling, and TanStack Router for type-safe navigation. This stack enables compile-time type checking and runtime flexibility through utility-first CSS classes.
How does open-seo prevent feature components from duplicating core UI code?
Feature components live in src/client/features/ and import primitives from src/client/components/. For example, the keywords feature composes AppDataTable, Sidebar, and Button components rather than rebuilding table or navigation logic, ensuring visual consistency while isolating domain logic.
What styling approach makes open-seo components themeable?
Components use Tailwind utility classes embedded directly in JSX markup, as seen in web/src/components/site-footer.tsx. This eliminates external CSS dependencies and allows consistent theming through Tailwind's configuration system and DaisyUI's component classes.
Can open-seo components be used across both the dashboard and marketing site?
While the architecture separates dashboard components (src/client/components/) from marketing components (web/src/components/), both follow identical React and TypeScript patterns. Core primitives could theoretically be shared, though the current structure keeps them distinct to accommodate different design requirements between the internal tool and public site.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →