> ## 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.

# Creating Themes

> Learn how to create custom themes for your EverShop store

Themes control the visual appearance and user interface of your EverShop store. Unlike extensions (which handle logic), themes focus on the presentation layer using React components and Tailwind CSS.

## What is a Theme?

A theme is a collection of React components that define how your store looks and feels. Themes:

* **Override default UI components** with custom designs
* **Use Tailwind CSS** for styling
* **Support TypeScript** for type-safe development
* **Are modular** - only override components you need
* **Work with areas** - inject components into predefined page areas

## Directory Structure

A typical theme follows this structure:

```
themes/[theme-name]/
├── src/
│   └── pages/
│       ├── all/            # Components for all pages
│       ├── frontStore/     # Front-end specific components
│       ├── admin/          # Admin panel components
│       ├── homepage/       # Homepage components
│       ├── account/        # Account pages
│       └── productView/    # Product detail page
├── dist/                   # Compiled output (auto-generated)
├── package.json
└── tsconfig.json
```

## Creating Your First Theme

<Steps>
  ### Create the Theme Directory

  Create a new directory in the `themes` folder:

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

  ### Initialize package.json

  Create a `package.json` file:

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

  ### Configure TypeScript

  Create a `tsconfig.json` file (same as extensions):

  ```json theme={null}
  {
    "compilerOptions": {
      "module": "NodeNext",
      "target": "ES2018",
      "lib": ["dom", "dom.iterable", "esnext"],
      "esModuleInterop": true,
      "forceConsistentCasingInFileNames": true,
      "skipLibCheck": true,
      "declaration": true,
      "sourceMap": true,
      "allowJs": true,
      "checkJs": false,
      "jsx": "react",
      "outDir": "./dist",
      "resolveJsonModule": true,
      "allowSyntheticDefaultImports": true,
      "allowArbitraryExtensions": true,
      "strictNullChecks": true,
      "isolatedModules": false,
      "baseUrl": ".",
      "rootDir": "./src"
    },
    "include": ["src"]
  }
  ```

  ### Register the Theme

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

  ```json theme={null}
  {
    "system": {
      "theme": "my-theme"
    }
  }
  ```

  <Warning>
    Only one theme can be active at a time. Changing the theme requires running `npm run build`.
  </Warning>

  ### Build the Theme

  Run the build command:

  ```bash theme={null}
  npm run build
  ```
</Steps>

## Creating Theme Components

Theme components are React components that render on specific pages. Each component must export:

1. **Default export** - The React component
2. **layout export** - Defines where and when the component renders
3. **query export** (optional) - GraphQL query for data fetching

### Component Structure

Here's a real example from the `anasuplements` theme:

```tsx title="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 = "My Store", 
  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]">
              <svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z" />
              </svg>
            </a>
            <a href="/account" className="text-[#2D5A3D] hover:text-[#1E3D2A]">
              <svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
              </svg>
            </a>
          </div>
        </div>
      </div>
    </header>
  );
}

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

### Layout Configuration

The `layout` export defines where your component appears:

```typescript theme={null}
export const layout = {
  areaId: 'header',      // Where to render (see Areas below)
  sortOrder: 1           // Order within the area (lower = earlier)
};
```

## Page Areas

EverShop uses a component area system. Common areas include:

| Area ID                  | Description               |
| ------------------------ | ------------------------- |
| `header`                 | Page header section       |
| `content`                | Main content area         |
| `footer`                 | Page footer section       |
| `sidebar`                | Sidebar area              |
| `productPageMiddleRight` | Product page right column |
| `homepage`               | Homepage specific area    |

<Tip>
  Use lower `sortOrder` values to render components earlier in the area.
</Tip>

## Directory Organization

Theme components are organized by page type:

### Global Components (all/)

Components in `src/pages/all/` appear on every page:

```
src/pages/all/
├── Header.tsx     # Site header
├── Footer.tsx     # Site footer
└── Navigation.tsx # Global navigation
```

### Area-Specific Components

Components for specific areas (frontStore, admin):

```
src/pages/frontStore/
└── productView/
    └── ProductInfo.tsx

src/pages/admin/
└── dashboard/
    └── Stats.tsx
```

### Page-Specific Components

Components for specific pages:

```
src/pages/homepage/
├── Hero.tsx
├── Features.tsx
└── FeaturedProducts.tsx

src/pages/account/
├── Login.tsx
├── Register.tsx
└── Dashboard.tsx
```

## Working with Data

Use the `query` export to fetch data with GraphQL:

```tsx title="src/pages/frontStore/productView/SupplementInfo.tsx" theme={null}
import React from 'react';

type SupplementInfoProps = {
  product: {
    productId: string;
    name: string;
    description?: string;
    extension?: {
      supplement?: {
        ingredients?: string;
        benefits?: string[];
        dosage?: string;
      };
    };
  };
};

export default function SupplementInfo({ product }: SupplementInfoProps) {
  const supplementData = product?.extension?.supplement;

  if (!supplementData) {
    return null;
  }

  return (
    <div className="bg-[#F8FAF9] border border-[#E8F5E9] rounded-lg p-6 mt-6">
      <h3 className="text-xl font-bold text-[#2D5A3D] mb-4">
        Información del Suplemento
      </h3>
      
      {supplementData.ingredients && (
        <div>
          <h4 className="font-semibold text-[#2D5A3D] mb-2">Ingredientes</h4>
          <p className="text-[#4A5568] text-sm">{supplementData.ingredients}</p>
        </div>
      )}
      
      {supplementData.benefits && (
        <div className="mt-4">
          <h4 className="font-semibold text-[#2D5A3D] mb-2">Beneficios</h4>
          <ul className="list-disc list-inside text-[#4A5568] text-sm space-y-1">
            {supplementData.benefits.map((benefit: string, index: number) => (
              <li key={index}>{benefit}</li>
            ))}
          </ul>
        </div>
      )}
    </div>
  );
}

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

export const query = `
  query Query {
    product(id: getContextValue("productId")) {
      productId
      name
      description
      extension {
        supplement {
          ingredients
          benefits
          dosage
        }
      }
    }
  }
`;
```

<Note>
  The `query` export uses GraphQL to fetch data. Props are automatically passed to your component.
</Note>

## Styling with Tailwind CSS

All themes use Tailwind CSS for styling:

```tsx theme={null}
<div className="bg-white rounded-lg shadow-md p-6 hover:shadow-lg transition-shadow">
  <h3 className="font-semibold mb-3 text-gray-800">Title</h3>
  <p className="text-gray-600 leading-relaxed">Content</p>
</div>
```

### Custom Colors

Use custom color values with bracket notation:

```tsx theme={null}
<header className="bg-[#F8FAF9] border-b border-[#E8F5E9]">
  <h1 className="text-[#2D5A3D]">Title</h1>
</header>
```

### Responsive Design

Use responsive modifiers:

```tsx theme={null}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
  {/* Content */}
</div>
```

## Real-World Example: Ana's Supplements Theme

The `anasuplements` theme demonstrates a complete theme implementation:

```
themes/anasuplements/
├── src/
│   └── pages/
│       ├── all/
│       │   ├── Header.tsx
│       │   └── Footer.tsx
│       ├── homepage/
│       │   ├── Hero.tsx
│       │   ├── Features.tsx
│       │   └── FeaturedProducts.tsx
│       └── account/
│           ├── Login.tsx
│           ├── Register.tsx
│           └── Dashboard.tsx
├── package.json
└── tsconfig.json
```

## Best Practices

<Tip>
  **Component Reusability**: Create small, reusable components that can be composed together.
</Tip>

* **Use TypeScript** - Define proper types for props
* **Responsive First** - Design for mobile, then scale up
* **Accessibility** - Use semantic HTML and ARIA labels
* **Performance** - Optimize images and minimize bundle size
* **Consistent Styling** - Use a consistent color palette and spacing

## Troubleshooting

### Component Not Rendering

1. Verify the `layout` export is present
2. Check that `areaId` matches a valid area
3. Ensure the component is in the correct directory
4. Run `npm run build` to recompile

### Styles Not Applying

1. Verify Tailwind CSS classes are correct
2. Check for typos in class names
3. Ensure custom colors use bracket notation: `bg-[#FFFFFF]`

### Data Not Loading

1. Verify the GraphQL query is valid
2. Check that field names match the schema
3. Test the query in GraphQL playground

## Next Steps

<CardGroup cols={2}>
  <Card title="Page Components" icon="window" href="/guides/page-components">
    Deep dive into page component architecture
  </Card>

  <Card title="Tailwind Design System" icon="palette" href="/concepts/themes">
    Learn about the Tailwind design system
  </Card>
</CardGroup>
