> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Antony-Figueroa/my-evershop-app/llms.txt
> Use this file to discover all available pages before exploring further.

# Themes

> Learn how to customize your store's appearance with the EverShop theme system

# Themes

Themes in EverShop control the visual presentation and user interface of your store. They contain React components that render the pages your customers see, while keeping business logic separate in extensions.

## What are Themes?

Themes provide:

* Visual design and styling with Tailwind CSS
* React components for pages and UI elements
* Responsive layouts for mobile and desktop
* Brand customization (colors, fonts, logos)
* User experience enhancements

<Note>
  **Extensions vs Themes**: Extensions handle business logic (APIs, GraphQL, cron jobs), while themes handle presentation (React components, styling). This separation allows you to change your store's appearance without affecting functionality.
</Note>

## Directory Structure

Themes live in the `themes/` directory:

```plaintext theme={null}
themes/[theme-name]/
├── src/
│   └── pages/           # Page components organized by area
│       ├── all/         # Components for all pages (Header, Footer)
│       ├── homepage/    # Homepage-specific components
│       ├── account/     # Account pages (Login, Register, Dashboard)
│       └── [area]/      # Other page areas
├── dist/                # Compiled files (auto-generated)
├── package.json
└── tsconfig.json
```

## Activating a Theme

Set your active theme in `config/default.json`:

```json config/default.json theme={null}
{
  "system": {
    "theme": "anasuplements"
  }
}
```

<Tip>
  You can only have one active theme at a time. The theme name must match a directory in `themes/`.
</Tip>

## Creating a Theme

<Steps>
  ### Create the directory structure

  ```bash theme={null}
  mkdir -p themes/myTheme/src/pages
  ```

  ### Add package.json

  ```json themes/myTheme/package.json theme={null}
  {
    "name": "myTheme",
    "version": "1.0.0",
    "private": true,
    "main": "src/index.ts",
    "scripts": {
      "build": "evershop build:theme"
    },
    "devDependencies": {
      "@types/react": "^19.0.0"
    }
  }
  ```

  ### Configure TypeScript

  ```json themes/myTheme/tsconfig.json theme={null}
  {
    "extends": "../../tsconfig.json",
    "compilerOptions": {
      "outDir": "./dist",
      "rootDir": "./src",
      "jsx": "react"
    },
    "include": ["src/**/*"]
  }
  ```

  ### Activate the theme

  Update `config/default.json`:

  ```json theme={null}
  {
    "system": {
      "theme": "myTheme"
    }
  }
  ```
</Steps>

## Page Components

Page components are React components with special exports that tell EverShop where and when to render them.

### Basic Component Structure

Every theme component needs:

1. A default export (the React component)
2. A `layout` export (defines placement and order)
3. Optional `query` export (for GraphQL data fetching)

```tsx themes/anasuplements/src/pages/homepage/Hero.tsx theme={null}
import React from 'react';

export default function Hero() {
  return (
    <section className="bg-[#F8FAF9] py-16">
      <div className="container mx-auto px-4">
        <div className="text-center">
          <h1 className="text-4xl md:text-5xl font-bold text-[#2D5A3D] mb-4">
            Bienvenido a Ana's Suplements
          </h1>
          <p className="text-lg text-[#4A5568] mb-8 max-w-2xl mx-auto">
            Los mejores suplementos para tu salud y bienestar.
          </p>
          <div className="flex justify-center gap-4">
            <a 
              href="/catalog" 
              className="bg-[#2D5A3D] text-white px-8 py-3 rounded-lg hover:bg-[#1E3D2A] transition-colors font-semibold"
            >
              Ver Catálogo
            </a>
            <a 
              href="/contact" 
              className="border-2 border-[#2D5A3D] text-[#2D5A3D] px-8 py-3 rounded-lg hover:bg-[#2D5A3D] hover:text-white transition-colors font-semibold"
            >
              Contactar
            </a>
          </div>
        </div>
      </div>
    </section>
  );
}

export const layout = {
  areaId: 'content',
  sortOrder: 1
};
```

### Layout Export

The `layout` export determines where the component appears:

```typescript theme={null}
export const layout = {
  areaId: 'content',     // Which area to render in
  sortOrder: 10          // Rendering order (lower numbers render first)
};
```

Common `areaId` values:

* `header` - Top of all pages
* `footer` - Bottom of all pages
* `content` - Main content area
* `productPageBottom` - Below product details
* `checkoutPaymentMethod` - Payment method selection area

### GraphQL Data Fetching

Use the `query` export to fetch data:

```tsx themes/anasuplements/src/pages/all/Header.tsx theme={null}
import React from 'react';

type HeaderProps = {
  storeName?: string;
  categories?: {
    name: string;
    url: string;
  }[];
};

export default function Header({ storeName = "Ana's Suplements", categories = [] }: HeaderProps) {
  return (
    <header className="bg-[#F8FAF9] border-b border-[#E8F5E9]">
      <div className="container mx-auto px-4 py-4">
        <div className="flex items-center justify-between">
          <a href="/" className="text-2xl font-bold text-[#2D5A3D]">
            {storeName}
          </a>
          
          <nav className="hidden md:flex space-x-6">
            {categories.map((category, index) => (
              <a 
                key={index} 
                href={category.url}
                className="text-[#4A5568] hover:text-[#2D5A3D] transition-colors"
              >
                {category.name}
              </a>
            ))}
          </nav>

          <div className="flex items-center space-x-4">
            <a href="/cart" className="text-[#2D5A3D] hover:text-[#1E3D2A]">
              {/* Cart icon SVG */}
            </a>
            <a href="/account" className="text-[#2D5A3D] hover:text-[#1E3D2A]">
              {/* Account icon SVG */}
            </a>
          </div>
        </div>
      </div>
    </header>
  );
}

export const layout = {
  areaId: 'header',
  sortOrder: 1
};

export const query = `
  query Query {
    storeName: setting(key: "storeName")
    categories {
      name
      url
    }
  }
`;
```

## Page Areas

Organize components by the pages they appear on:

### Global Components (`all/`)

Components that appear on every page:

```plaintext theme={null}
src/pages/all/
├── Header.tsx
└── Footer.tsx
```

### Homepage Components (`homepage/`)

Components specific to the homepage:

```tsx themes/anasuplements/src/pages/homepage/FeaturedProducts.tsx theme={null}
import React from 'react';

type ProductCardProps = {
  product: {
    id: string;
    name: string;
    price: number;
    image?: string;
  };
};

function ProductCard({ product }: ProductCardProps) {
  return (
    <div className="bg-white rounded-lg shadow-sm hover:shadow-md transition-shadow border border-[#E8F5E9] overflow-hidden">
      <div className="aspect-square bg-[#F8FAF9] flex items-center justify-center">
        {product.image ? (
          <img src={product.image} alt={product.name} className="w-full h-full object-cover" />
        ) : (
          <svg className="w-16 h-16 text-[#A0C4B0]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1} d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" />
          </svg>
        )}
      </div>
      <div className="p-4">
        <h3 className="font-semibold text-[#2D5A3D] mb-2 line-clamp-2">
          {product.name}
        </h3>
        <div className="flex items-center justify-between">
          <span className="text-lg font-bold text-[#2D5A3D]">
            ${product.price?.toFixed(2)}
          </span>
          <button className="bg-[#2D5A3D] text-white px-4 py-2 rounded text-sm hover:bg-[#1E3D2A] transition-colors">
            Agregar
          </button>
        </div>
      </div>
    </div>
  );
}

export default function FeaturedProducts() {
  const products = [
    { id: '1', name: 'Vitamina D3', price: 15.99 },
    { id: '2', name: 'Omega-3', price: 24.99 },
    { id: '3', name: 'Proteína Whey', price: 45.99 },
    { id: '4', name: 'Magnesio', price: 18.99 },
  ];

  return (
    <section className="py-16">
      <div className="container mx-auto px-4">
        <h2 className="text-3xl font-bold text-center text-[#2D5A3D] mb-4">
          Productos Destacados
        </h2>
        <p className="text-center text-[#4A5568] mb-8">
          Los suplementos más populares de nuestra tienda
        </p>
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
          {products.map((product) => (
            <ProductCard key={product.id} product={product} />
          ))}
        </div>
      </div>
    </section>
  );
}

export const layout = {
  areaId: 'content',
  sortOrder: 10
};
```

### Account Pages (`account/`)

User account-related components:

```plaintext theme={null}
src/pages/account/
├── Login.tsx
├── Register.tsx
└── Dashboard.tsx
```

## Styling with Tailwind CSS

EverShop uses Tailwind CSS for styling. The Ana's Suplements theme uses a custom color palette:

```tsx theme={null}
{/* Primary green */}
className="text-[#2D5A3D] bg-[#2D5A3D]"

{/* Hover state */}
className="hover:bg-[#1E3D2A]"

{/* Background */}
className="bg-[#F8FAF9]"

{/* Borders */}
className="border border-[#E8F5E9]"

{/* Text colors */}
className="text-[#4A5568]"
```

<Tip>
  Use Tailwind's utility classes for responsive design:

  * `sm:` - Small screens (640px+)
  * `md:` - Medium screens (768px+)
  * `lg:` - Large screens (1024px+)
  * `xl:` - Extra large screens (1280px+)
</Tip>

## TypeScript Props

Always define TypeScript types for your component props:

```tsx theme={null}
type MyComponentProps = {
  title: string;
  description?: string;  // Optional prop
  items: Array<{
    id: string;
    name: string;
  }>;
  onSubmit?: (data: FormData) => void;
};

export default function MyComponent({ 
  title, 
  description, 
  items, 
  onSubmit 
}: MyComponentProps) {
  // Component implementation
}
```

## Accessing EverShop Hooks

EverShop provides React hooks for common operations:

```tsx theme={null}
import { useCheckout } from '@evershop/evershop';

export default function PaymentMethod() {
  const checkout = useCheckout();
  const { paymentMethods, setPaymentMethods } = checkout;
  
  // Use checkout data and methods
}
```

## Best Practices

<Accordion title="Use semantic component names">
  Name components based on what they represent, not how they look:

  * Good: `ProductCard`, `HeroSection`, `FeaturedProducts`
  * Bad: `GreenBox`, `BigText`, `ThreeColumns`
</Accordion>

<Accordion title="Keep components focused and reusable">
  Break large components into smaller, reusable pieces:

  ```tsx theme={null}
  // Instead of one large component
  <ProductGrid />

  // Break it down
  <ProductGrid>
    <ProductCard />
    <ProductCard />
  </ProductGrid>
  ```
</Accordion>

<Accordion title="Use Tailwind classes directly">
  Avoid custom CSS files. Use Tailwind utility classes for all styling:

  ```tsx theme={null}
  // Good
  <div className="bg-white rounded-lg shadow-md p-6">

  // Avoid
  <div className="custom-card-style">
  ```
</Accordion>

<Accordion title="Maintain consistent spacing">
  Use Tailwind's spacing scale consistently:

  * `p-4`, `p-6`, `p-8` for padding
  * `mb-4`, `mb-6`, `mb-8` for margins
  * `gap-4`, `gap-6`, `gap-8` for grid/flex gaps
</Accordion>

## anasuplements Theme Example

The included Ana's Suplements theme demonstrates:

* **Custom color palette**: Green (#2D5A3D) with pearl white backgrounds
* **Responsive design**: Mobile-first layouts that adapt to larger screens
* **Component organization**: Logical separation of homepage, account, and global components
* **TypeScript types**: Proper type definitions for all props
* **Tailwind styling**: Consistent use of utility classes

```plaintext themes/anasuplements/ theme={null}
├── src/pages/
│   ├── all/
│   │   ├── Header.tsx       # Global navigation
│   │   └── Footer.tsx       # Global footer
│   ├── homepage/
│   │   ├── Hero.tsx         # Hero banner
│   │   ├── Features.tsx     # Feature highlights
│   │   └── FeaturedProducts.tsx  # Product showcase
│   └── account/
│       ├── Login.tsx        # Login form
│       ├── Register.tsx     # Registration form
│       └── Dashboard.tsx    # Account dashboard
├── package.json
└── tsconfig.json
```

## Next Steps

* Learn about [Extensions](/concepts/extensions) for adding functionality
* Understand [Routing](/concepts/routing) for page configuration
* Explore the [GraphQL API](/concepts/graphql) for data fetching
