> ## Documentation Index
> Fetch the complete documentation index at: https://spreecommerce.org/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Storefront Themes

> Create and customize themes for the Spree Rails Storefront, including theme generators, template structure, and registering themes with the Page Builder.

<Warning>
  We recommend using [Next.js Storefront](/developer/storefront/nextjs) for new projects, as it offers better performance and a more modern developer experience.
</Warning>

Themes are the main building blocks of the storefront. They hold styles, settings, and templates for the storefront.

## Default Theme

Spree comes with a default theme called `default`. It is used as a base for all the themes and contains the core styles and scripts. This theme is included with the Spree Commerce core and is always available.

## Creating a New Theme

You can create your custom themes by following the steps below.

<CodeGroup>
  ```bash Spree CLI (Docker) theme={"theme":"night-owl"}
  spree generate spree:storefront:theme MyTheme
  ```

  ```bash Without Spree CLI theme={"theme":"night-owl"}
  bin/rails g spree:storefront:theme MyTheme
  ```
</CodeGroup>

This command will create a new theme called `my_theme` in the `app/views/themes` directory and copy the default theme files to the new theme.

It will also add a line in your `config/initializers/spree.rb` file to load the new theme.

```ruby config/initializers/spree.rb theme={"theme":"night-owl"}
Spree.page_builder.themes << Spree::Themes::MyTheme
```

Now you can go to **Admin Dashboard -> Storefront -> Themes**, you should see a new section **Add new theme** with your theme name. Click **Add** button to activate the theme.

### Theme Templates

Theme has the following template structure:

```
├── account
│   ├── store_credits
│   ├── profile
│   ├── orders
│   ├── newsletter
│   └── addresses
├── checkout
├── contacts
├── orders
├── page_sections
├── policies
├── posts
├── products
├── search
├── settings
├── shared
└── wishlists
```

Each directory contains standard [Ruby on Rails ERB templates](https://guides.rubyonrails.org/action_view_overview.html) for the corresponding page.

The `page_sections` directory contains sections that are used globally across the storefront.

The `shared` directory contains shared components that are used across the storefront.

### Theme Settings

The theme settings are stored in the `app/models/spree/themes/my_theme.rb` file.

```ruby theme={"theme":"night-owl"}
module Spree
  module Themes
    class MyTheme < Spree::Theme
      def self.metadata
        {
          authors: ['Spree Commerce'], # replace with your name
          license: 'MIT' # replace with your license
        }
      end

      # COLORS
      # main colors
      preference :primary_color, :string, default: '#000000'
      preference :accent_color, :string, default: '#F0EFE9'
      preference :danger_color, :string, default: '#C73528'
      preference :neutral_color, :string, default: '#999999'
      preference :background_color, :string, default: '#FFFFFF'
      preference :text_color, :string, default: '#000000'
      preference :success_color, :string, default: '#00C773'

      # buttons
      preference :button_background_color, :string
      preference :button_text_color, :string, default: '#ffffff'
      preference :button_hover_background_color, :string
      preference :button_hover_text_color, :string
      preference :button_border_color, :string

      # borders
      preference :border_color, :string, default: '#E9E7DC'
      preference :sidebar_border_color, :string

      preference :secondary_button_background_color, :string
      preference :secondary_button_text_color, :string
      preference :secondary_button_hover_background_color, :string
      preference :secondary_button_hover_text_color, :string

      # inputs
      preference :input_text_color, :string, default: '#6b7280'
      preference :input_background_color, :string, default: '#ffffff'
      preference :input_border_color, :string
      preference :input_focus_border_color, :string
      preference :input_focus_background_color, :string
      preference :input_focus_text_color, :string

      # sidebar (checkout)
      preference :checkout_sidebar_background_color, :string, default: '#f3f4f6'
      preference :checkout_divider_background_color, :string
      preference :checkout_sidebar_text_color, :string

      # TYPOGRAPHY
      preference :custom_font_code, :string, default: nil
      # body
      preference :font_family, :string, default: 'Inter'
      preference :font_size_scale, :integer, default: 100
      # headers
      preference :header_font_family, :string, default: 'Inter'
      preference :header_font_size_scale, :integer, default: 100
      preference :headings_uppercase, :boolean, default: true

      # BUTTONS
      preference :button_border_thickness, :integer, default: 1
      preference :button_border_opacity, :integer, default: 100
      preference :button_border_radius, :integer, default: 100
      preference :button_shadow_opacity, :integer, default: 0
      preference :button_shadow_horizontal_offset, :integer, default: 0
      preference :button_shadow_vertical_offset, :integer, default: 4
      preference :button_shadow_blur, :integer, default: 5

      # INPUTS
      preference :input_border_thickness, :integer, default: 1
      preference :input_border_opacity, :integer, default: 100
      preference :input_border_radius, :integer, default: 8
      preference :input_shadow_opacity, :integer, default: 0
      preference :input_shadow_horizontal_offset, :integer, default: 0
      preference :input_shadow_vertical_offset, :integer, default: 4
      preference :input_shadow_blur, :integer, default: 5

      # BORDERS
      preference :border_width, :integer, default: 1
      preference :border_radius, :integer, default: 6
      preference :border_shadow_opacity, :integer, default: 0
      preference :border_shadow_horizontal_offset, :integer, default: 0
      preference :border_shadow_vertical_offset, :integer, default: 4
      preference :border_shadow_blur, :integer, default: 5

      # PRODUCT IMAGES
      preference :product_listing_image_height, :integer, default: 300
      preference :product_listing_image_width, :integer, default: 300
      preference :product_listing_image_height_mobile, :integer, default: 190
      preference :product_listing_image_width_mobile, :integer, default: 190
    end
  end
end
```

These are standard [Spree preferences](/developer/customization/model-preferences) that are configurable via Page Builder.
