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 own custom themes by following the steps below.

rails g spree:theme MyTheme

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.

Rails.application.config.spree.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 for the corresponding page.

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

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.

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 that are configurable via Page Builder.