Skip to main content
Support Center

Guidelines for creating a Custom Theme

In this article we will explain how you can create a Jumpseller Theme completely from scratch, covering topics such as the folders and files structure you need to have in place, through how to upload or import it to your store, as well as how you can start creating components and subcomponents which are the building blocks that will allow you to customize a theme.

As a start you need to know that a Jumpseller theme is built using a combination of HTML, CSS, JavaScript and Liquid — Jumpseller’s templating language. If you are familiar with how Liquid works in platforms like Shopify, you will find it very similar. If not, don’t worry: we have a dedicated article to get you started with Liquid in Jumpseller.


Folder and File Structure

Before uploading anything, you need to prepare your theme as a .zip file that follows a specific folder and file structure. Jumpseller will not recognize a theme that deviates from this structure, so it is important to get it right from the beginning.

You can download a very basic version of a theme to get started: Download my-custom-theme.zip

Here is what the downloaded theme looks like:

my-custom-theme/
├── assets/
│   ├── app.css
│   └── theme.js
├── components/
│   ├── header.json
│   ├── header.liquid
│   ├── footer.json
│   └── footer.liquid
├── config/
│   ├── installed-components.json
│   ├── options.json
│   ├── pages.json
│   ├── settings.json
│   ├── theme.json
│   └── variants.json
├── locales/
├── partials/
│   └── schema.liquid
└── templates/
    ├── layout.liquid
    ├── home.liquid
    ├── contactpage.liquid
    ├── error.liquid
    ├── searchresults.liquid
    ├── category/
    │   └── Default.liquid
    ├── checkout/
    │   ├── cart.liquid
    │   ├── checkout.liquid
    │   ├── revieworder.liquid
    │   └── success.liquid
    ├── customer/
    │   ├── account.liquid
    │   ├── address.liquid
    │   ├── details.liquid
    │   ├── login.liquid
    │   └── reset_password.liquid
    ├── page/
    │   ├── Default.liquid
    │   └── Post.liquid
    ├── page_category/
    │   ├── Blog.liquid
    │   └── Default.liquid
    └── product/
        └── Default.liquid

Let’s go through each folder and what it contains.


The config Folder

The config folder holds all the JSON files that define how your theme behaves, what options it exposes to the store owner, and how it integrates with Jumpseller’s Visual Editor. This is the most critical folder in terms of configuration.

theme.json

This is the main identity file of your theme. It tells Jumpseller who made the theme, what version it is, and what capabilities it supports. It also defines the navigation menus that the theme uses.

{
  "Info": {
    "name": "My custom theme",
    "author": "Jumpseller",
    "default_lang": "en",
    "use_system_translations": true,
    "version": "1.0.0",
    "capabilities": [
      "multicurrency",
      "product_appointments",
      "product_price_lists",
      "product_subscriptions",
      "product_wishlists"
    ]
  },
  "Menus": {
    "main": {
      "name": "Main Menu"
    },
    "footer_1": {
      "name": "Footer Menu 1"
    },
    "footer_2": {
      "name": "Footer Menu 2"
    }
  }
}

Note: The capabilities array tells Jumpseller which advanced features your theme supports. Only include capabilities that your theme actually implements — for example, multicurrency if your theme handles multiple currencies in the UI.

settings.json

This file defines the color schemes (also called color bundles or color packs) that are available for your theme. Each color variant has an identifier (its display name) and an options object containing the actual color values.

{
  "active": {
    "color": {
      "default": {
        "identifier": "Content",
        "options": {
          "background": "#FFFFFF",
          "main": "#261C15",
          "secondary": "#35271D",
          "links": "#007EA7",
          "main_button_background": "#261C15",
          "main_button_text": "#F5F5F5",
          "secondary_button_background": "#6B818C",
          "secondary_button_text": "#FFFFFF"
        }
      }
    }
  }
}

The color keys defined here can be used in your CSS as custom properties (CSS variables), allowing store owners to switch between color schemes directly from the Visual Editor without touching any code.

options.json

This file defines the general theme options that store owners can configure from the Visual Editor. Options are grouped into named groups, each with an icon and a set of individual options.

{
  "groups": {
    "option-group": {
      "name": "Options",
      "icon": "tint",
      "options": {
        "theme_option": {
          "name": "Option name",
          "type": "input"
        }
      }
    }
  }
}

Options can be of many different types — input, checkbox, select, and color are just a few examples. You can review the full list of available option types in this article.

Once defined here, they become accessible in your Liquid templates via the options object — for example, {{ options.theme_option }}.

variants.json

This file defines theme variants — predefined style combinations that store owners can select. For a theme starting from scratch, this file can start as an empty object:

{}

Even though it starts empty, variants.json is where you can define theme variations — predefined configurations that store owners can switch between from the Visual Editor. A common use case is offering a Light and a Dark version of your theme, where each variant can define:

  • Different general settings — for example, different color schemes, font choices, or any other option defined in options.json.
  • Different installed components — a variant could include additional components on the homepage that another variant doesn’t have.
  • Different component settings — components shared across variants can have their individual options pre-set differently per variant (e.g., a banner with different text or a layout toggle set to a different default).

This allows developers to ship multiple “looks” within a single theme, giving store owners a quick way to change the overall style of their store without having to manually reconfigure every setting.

installed-components.json

This file defines which components are installed in the theme by default and where they are placed. The two essential ones for any theme are header and footer:

{
  "header": {
    "type": "header",
    "placement": "top"
  },
  "footer": {
    "type": "footer",
    "placement": "bottom"
  }
}

The placement key tells Jumpseller whether the component lives at the top or bottom of a page, which maps to the {{ index_for_top_components }} and {{ index_for_bottom_components }} Liquid variables you will see in templates.

Beyond header and footer, this file is where you define all the components that come pre-installed when a store owner first applies your theme. For example, you could add a Slider component that gets installed on the homepage by default, or a Featured products component that appears on the product page out of the box.

These page-specific components are the ones rendered by the {{ index_for_components }} Liquid variable in each template — as opposed to the header and footer, which use the top and bottom placement variables instead.

Each entry in this file corresponds to a component that lives in the components/ folder, and those components are then referenced in pages.json to control on which page templates they appear.

In other words, installed-components.json is the source of truth for what comes bundled with the theme upon installation — it’s the developer’s way of defining the default experience a store owner gets the moment they activate the theme.

pages.json

This is a very important file — it defines which components are available on each page template in the Visual Editor. Each page type (home, product, category, etc.) represents a main template, and each one can have one or more sub-templates beneath it.

{
  "home": {
    "Default": {
      "components": [
        "header",
        "footer"
      ]
    }
  },
  "product": {
    "Default": {
      "components": [
        "header",
        "footer"
      ]
    },
    "Giftcard": {
      "components": [
        "header",
        "footer"
      ]
    }
  },
  "category": {
    "Default": {
      "components": [
        "header",
        "footer"
      ]
    },
    "Subcategories": {
      "components": [
        "header",
        "footer"
      ]
    }
  }
}

Note: Checkout pages (checkout__cart, checkout__checkout, etc.) typically have an empty components array because they use Jumpseller’s native checkout UI and do not support the Visual Editor component system.

For example, "product" is the main template for product pages, and "Default" is its default sub-template — the one that applies to standard products. You can then add additional sub-templates like "Giftcard", which would apply specifically to products of that type. Each sub-template defines its own list of components, giving developers fine-grained control over what the Visual Editor exposes depending on which sub-template is active.

The same logic applies to other page types. For "category", "Default" covers standard category pages, while a sub-template like "Subcategories" could be used to display a different layout for categories that contain nested subcategories instead of products directly.


The templates Folder

The templates folder contains all the Liquid files that define the HTML structure of each page of the store. The most important one is layout.liquid, which is the global wrapper where all other templates are rendered.

layout.liquid

This is the heart of your theme. It contains the full HTML document structure — the <html>, <head>, and <body> tags — and everything that needs to be present on every page of the store.

<!doctype html>
<html class="no-js" lang="{{ languages.first.locale }}" xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ page_title }}</title>
    <meta name="description" content="{{ meta_description | default: store.name }}">
    <meta name="robots" content="follow, all">

    <link rel="preconnect" href="https://images.jumpseller.com">
    <link rel="preconnect" href="https://cdnx.jumpseller.com">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

    {% for language in languages %}
      <link rel="alternate" 
        {% if languages.size > 1 %}
          hreflang="{{ language.locale }}"
        {% endif %} 
        href="{{ language.url }}"
      >
    {% endfor %}

    <link rel="canonical" href="{{ canonical_url }}">

    {{ favicon }}

    <!-- jQuery -->
    {{ 'jquery/4.0.0/jquery.min.js' | public_asset_tag: 'defer' }}

    <!-- Bootstrap -->
    {{ 'bootstrap/5.3.8/bootstrap.bundle.min.css' | public_asset_tag }}

    <!-- Theme Schema -->
    {% render 'schema' %}

    <!-- Main CSS file -->
    <link rel="stylesheet" href="{{ 'app.css' | asset }}">
  </head>

  <body>
    <script src="{{ 'theme.js' | asset }}" defer></script>
    <!-- Bootstrap JS -->
    {{ 'bootstrap/5.3.8/bootstrap.bundle.min.js' | public_asset_tag: 'defer' }}

    {{ content }}
  </body>
</html>

Some key things to note here:

  • {{ page_title }} — Outputs the SEO title for the current page, automatically set by Jumpseller.
  • {{ favicon }} — Outputs the <link> tag for the store’s favicon, which is managed from the admin panel under General > Branding.
  • {{ content }} — This is where the current page’s template content is rendered. Think of it as the “slot” where each page template gets injected into the layout.
  • {% render 'schema' %} — Renders the partials/schema.liquid file, which outputs structured data (JSON-LD) for SEO purposes.
  • public_asset_tag — A Liquid filter used to load shared public assets (like jQuery or Bootstrap) hosted by Jumpseller’s CDN.
  • asset — A Liquid filter used to reference files from your theme’s own assets/ folder.

Tip: JavaScript files should be loaded with the defer attribute to avoid render-blocking. CSS files for libraries like Bootstrap can be loaded synchronously in the <head>, while your own app.css should be tailored to load as efficiently as possible.

Page Templates

Every other .liquid file inside templates/ corresponds to a specific page type in the store. Most of them follow the same simple structure using three Liquid variables:

{{ index_for_top_components }}

{{ index_for_components }}

{{ index_for_bottom_components }}

These three variables are how Jumpseller’s Visual Editor inserts components into a page:

  • {{ index_for_top_components }} — Renders components that are placed at the top of the page (e.g., the header component).
  • {{ index_for_components }} — Renders the main components for that page (e.g., a product listing, a contact form).
  • {{ index_for_bottom_components }} — Renders components placed at the bottom (e.g., the footer component).

Here is a summary of all the page templates and what they represent:

File Page
home.liquid Store homepage
error.liquid 404 / error page
contactpage.liquid Contact page
searchresults.liquid Search results page
category/Default.liquid Product category page
product/Default.liquid Product detail page
page/Default.liquid Generic static page
page/Post.liquid Blog post page
page_category/Default.liquid Blog category listing
page_category/Blog.liquid Blog index page
checkout/cart.liquid Shopping cart
checkout/checkout.liquid Checkout form
checkout/revieworder.liquid Order review step
checkout/success.liquid Order confirmation page
customer/login.liquid Customer login page
customer/account.liquid Customer account overview
customer/details.liquid Customer personal details form
customer/address.liquid Customer address form
customer/reset_password.liquid Password reset form

Considerations

Some customer templates use special Liquid variables instead of the standard component variables, which render the native Jumpseller forms for those actions:

  • customer/details.liquid → uses {{ customer_details_form }}
  • customer/address.liquid → uses {{ customer_address_form }}
  • customer/reset_password.liquid → uses {{ customer_reset_password_form }}

The customer/details.liquid file is also used for the customer registration page (e.g. your-store.com/customer/registration). Even though its primary role is letting existing customers edit their personal details, the same template is rendered when a customer wants to register, so any changes to it will affect both flows.

Checkout templates (cart, checkout, revieworder, success) do support {{ index_for_top_components }} and {{ index_for_bottom_components }}, but they are intentionally left out of the theme’s files. The behavior depends on the checkout form version defined in the store’s admin panel:

  • Checkout version 1 (Classic): The four checkout pages can be fully customized with code, so top and bottom components will render across all four steps if added.
  • Checkout version 2 (Standard): Top and bottom components only render on the Cart page, since the rest of the checkout process uses its own built-in flow.

Beyond version differences, omitting top and bottom components from checkout pages is also a deliberate UX decision. Headers and footers typically contain navigation links to many areas of the store, which can lead customers away from the checkout process.

That said, a developer can add {{ index_for_top_components }} and {{ index_for_bottom_components }} to any checkout template if the design calls for it.

For more details on checkout form versions and their differences, refer to the Checkout Options and Settings article.


The components Folder

Components are the building blocks of a Jumpseller theme. They are the sections that store owners can add, remove, reorder, and configure visually through the Visual Editor — without touching any code.

Each component consists of two files:

  • A .json file — defines the component’s metadata, settings, and options.
  • A .liquid file — contains the HTML/Liquid markup that renders the component on the page.

Component JSON File

Here is an example of a header.json:

{
  "name": "Header",
  "max_usage": 1,
  "required": true,
  "templates_in": [
    "home",
    "product",
    "category",
    "page",
    "page_category",
    "contactpage",
    "searchresults",
    "error",
    "customer__account",
    "customer__address",
    "customer__details",
    "customer__login",
    "customer__reset_password"
  ],
  "options": {},
  "traits": [
    {
      "type": "menu_links",
      "menus": ["main"]
    }
  ],
  "presets": [
    {
      "name": "Header",
      "category": "Core"
    }
  ]
}

The key properties are:

  • name — The display name of the component in the Visual Editor.
  • max_usage — How many times this component can be added to a single page. For a header or footer, this needs to have a value of 1.
  • required — If true, the component cannot be removed nor deleted from the template it is assigned to, though it can be hidden.
  • templates_in — The list of theme templates where a component can appear.
  • options — An object defining the configurable settings for this component (fonts, colors, toggle switches, etc.).
  • traits — Special integrations like menu_links, which connects the component to a specific store navigation menu.
  • presets — Defines how the component appears in the Visual Editor’s component picker, including its display name and category grouping.

Component Liquid File

The .liquid file for a component is where you write its actual HTML markup and Liquid logic. For a theme starting from scratch, the component Liquid files are empty — they are ready for you to build out.

For example, header.liquid could be as simple as:

<header>
  {% if menu.main and menu.main.items.size > 0 %}
    <nav>
      {% for item in menu.main.items %}
        <a href="{{ item.url }}">{{ item.name }}</a>
      {% endfor %}
    </nav>
  {% endif %}
</header>

Components have access to the store’s Liquid objects (store, cart, customer, etc.) and to their own defined options via the options object.


The partials Folder

Partials are reusable Liquid snippets that can be included inside templates or components using the {% render 'partial_name' %} tag. They are not components — store owners cannot add or configure them through the Visual Editor — but their output is still rendered on the page wherever they are called.

The theme comes with one partial already in place:

partials/schema.liquid

This file outputs structured data in JSON-LD format, which helps search engines understand the content of each page. It handles multiple page types using a {% case template %} block:

  • On product pages: outputs Product schema with pricing, availability, and offer details.
  • On contact pages: outputs Store schema with address and location data.
  • On the homepage: outputs WebSite schema with a SearchAction for Google’s sitelinks search box.
  • On category, product, page, page_category and contactpage: outputs a BreadcrumbList schema.

It is rendered in layout.liquid via:

{% render 'schema' %}

Tip: You can create as many partials as you need. Common uses include: product cards, pagination blocks, social sharing buttons, or any piece of UI that repeats across multiple templates or components.


The assets Folder

The assets folder holds your theme’s static files — CSS, JavaScript, fonts, images, and any other assets that are not Liquid templates.

At minimum, a theme has two files here:

  • app.css — The main stylesheet for your theme. This is where your custom styles live.
  • theme.js — The main JavaScript file for your theme.

To reference these files in your templates, use the asset Liquid filter:

<link rel="stylesheet" href="{{ 'app.css' | asset }}">
<script src="{{ 'theme.js' | asset }}" defer></script>

The locales Folder

The locales folder stores translation files for your theme. These are JSON files that map translation keys to their translated strings, one file per language.

Jumpseller themes should be translated into the store’s supported languages. Translation strings are used in Liquid templates with the {% t 'key' %} tag.

Tip: If you set "use_system_translations": true in your theme.json, Jumpseller will automatically apply its own built-in translation strings for common UI elements (like “Add to cart”, “Out of stock”, etc.), so you don’t need to define them yourself.


Uploading Your Theme

Once your theme files are ready and organized in the correct structure, compress the root folder into a .zip file. The compressed file should contain a single root folder (e.g., my-custom-theme/) with all the files inside it.

Then, in your Jumpseller administration panel:

  1. Go to Themes → Gallery.
  2. Click Import on the top right corner.
  3. Select your .zip file and confirm.

Our system will validate the structure of your .zip file and, if everything is in order, the theme will be installed. If there are any errors, it will let you know which files or configurations are missing or incorrect.


Next Steps

With your theme uploaded, you are ready to start building. Here are some good next steps:

  • Add content to your component Liquid files — Start with header.liquid and footer.liquid to get a basic page structure visible.
  • Define your color scheme — Use CSS custom properties in app.css that map to the color keys defined in settings.json.
  • Create additional components — Each new section of your theme (a banner, a slider, a product collection, a newsletter section) should be its own component so store owners can manage it from the Visual Editor.
  • Explore Liquid — Read our Liquid documentation to learn all the objects, filters, and tags available to you.

Theme Compliance Guidelines

Once your theme is built, it needs to meet a set of standards to be fully compatible with Jumpseller’s features and to provide a consistent, quality experience for store owners and their customers.

The following guidelines are organized by topic and split into must-haves — requirements that are non-negotiable for a compliant theme — and nice-to-haves — recommendations that significantly improve quality but are not strictly mandatory.


General

Must-haves

  • The theme must be fully responsive and work correctly across all screen sizes and devices — including desktops, tablets, and mobile phones.
  • Markup must be W3C HTML compliant and styles must be W3C CSS compliant.
  • Arbitrary inline CSS should be avoided — all styles should live in one or more CSS asset files. The exception is the use of a {% style %} block in layout.liquid to output theme settings as CSS custom properties (e.g. color bundles, font choices), which is an accepted and common pattern in Jumpseller themes.
  • External resource URLs should omit the protocol (e.g. //resource.com/library.js instead of https://resource.com/library.js) to prevent mixed-content warnings.
  • JavaScript and CSS should be deferred so they do not block page rendering.

Nice-to-haves

  • JavaScript libraries and plugins (frameworks, sliders or carousels like SwiperJS, animation libraries, etc.) should be kept updated to their latest stable release.
  • JavaScript libraries should be minified for better performance.

Must-haves

  • If the store only has one language defined, the language selector must not be displayed.
  • If the store only has one currency defined, the currency selector must not be displayed.
  • The main navigation must support at least 3 levels of depth (Category → Sub-category → Sub-sub-category).
  • If the menu contains many items, it must remain browsable on smaller screens — items should be scrollable or otherwise accessible when they overflow.

Nice-to-haves

  • Mobile navigation should be optimized for menus with many items, ensuring all sub-menus are reachable and easy to navigate on touch devices.

Must-haves

  • Display the store’s logo, linked to the homepage — using {{ store.logo }} for the image and {{ store.url }} for the link. If no logo has been uploaded, display the store name as a text fallback using {{ store.name }}.
  • Display the main navigation menu links — using menu.main.items wrapped in an {% if menu.main and menu.main.items.size > 0 %} guard.
  • Display a search input or search trigger, allowing customers to search the store’s product catalog.
  • Display a link or icon to the shopping cart, showing the current number of items — using {{ order.products_count }}.
  • Display the language selector when the store has more than one language defined.
  • Display the currency selector when the store has more than one currency defined.
  • Display a link to the customer account area if customer accounts are enabled in the store — using {{ store.customers_enabled }} to check this condition.
  • Display a wishlist icon or link if the feature is available for the store’s plan — using {{ store.wishlists_enabled }} to check this condition.

Nice-to-haves

  • A sticky header that remains visible as the customer scrolls down the page.
  • A mobile-friendly navigation menu (e.g. a hamburger menu) that collapses navigation links on smaller screens.
  • A promotional announcement bar above the header to display store-wide messages, discounts, or notices.

Must-haves

  • Display links from the footer navigation menus. The theme.json file comes with two footer menus pre-defined (footer_1 and footer_2), but developers can create and include additional ones as needed.
  • Display links to all social networks set up in the store settings — including Instagram, Facebook, TikTok, YouTube, X (Twitter), and Pinterest, among others. If the theme design calls for it, icons can also be displayed alongside the links.
  • Display a copyright block showing: © [Current year] [Store name]. All Rights Reserved., followed by {{ powered_by }} — a Liquid tag that automatically outputs a “Powered by Jumpseller” link pointing to the Jumpseller homepage.

Nice-to-haves

  • Display contact options such as phone number and email address. Whether to show the contact email should be controllable via a theme option.
  • Display the store’s logo, description, and any other relevant store information that helps build trust with visitors.
  • Display the payment methods accepted by the store, so customers are aware of their options before reaching checkout.

Home Layout

Must-haves

  • A banner or slider component to display featured images and text.
  • A Featured products section, shown only if the corresponding theme option is enabled. The number of products displayed should be configurable via theme options.
  • A Latest products section, shown only if the corresponding theme option is enabled. The number of products displayed should be configurable via theme options.
  • A Blog area block, shown only if the corresponding theme option is enabled. It should display the latest pages assigned to the “Post” category, with the quantity configurable via theme options.

Nice-to-haves

  • An Instagram section or component connected to the merchant’s Instagram account.
  • A newsletter signup section or component connected to the store’s customer registration system.

Category Layout

Must-haves

  • Category name displayed in an <h1> tag.
  • Category image displayed if one has been uploaded by the merchant.
  • Category description displayed in an <h2> tag.
  • A product sort dropdown.
  • A paginated list of products in the category, with the number of products per page configurable via theme options.
  • Each product in the list must follow the Product Block standards described in the Products section below.
  • If the category has no products, display the message: “There aren’t any products available in this category.”
  • Support for product filters. See the documentation.

Nice-to-haves

  • Sticky or collapsible filter sidebar for improved UX on large product catalogs.

Search Results Layout

Must-haves

  • Page title “Search results” in an <h1> tag.
  • Display the number of results found.
  • Display the phrase “You’ve searched for:” followed by the search term.
  • A paginated list of matching products, following the Product Block standards.
  • If no results are found, display a message such as: “There aren’t any products that match your search. Try searching again.”
  • Support for product filters. See the documentation.

Nice-to-haves

  • Suggested search terms or alternative product recommendations when no results are found.

Products

Product Block (used in category, search, and other listing pages)

Must-haves

  • First product image, with a placeholder shown if no image has been uploaded.
  • The image must include an alt attribute containing the product name.
  • Product name in an <h3> tag.
  • Product price, and discounted price if applicable.
  • If the product and all its variants are out of stock, display: “Out of stock.”
  • If the product and all its variants are unavailable, display: “Not available.”
  • A link to the product page, placed on the product name, image, or any other element.

Product Page

Must-haves

  • Display multiple product images. If no image exists, show a placeholder with the message “There’s no product image available.”
  • Product images should update when a visitor selects a variant.
  • Display product brand if available.
  • Display product price and discounted price if applicable.
  • Display SKU and stock information for the product and its variants, if the corresponding theme options are enabled.
  • Display product custom fields if available.
  • Display product attachments if available (and the product is not virtual or digital).
  • Display product options if available.
  • Hide or disable the “Add to cart” button if the product or its selected variant is out of stock or unavailable.
  • The product description must render the most common HTML tags correctly: ol, ul, li, strong, a, p, br, table, i, s, b, h2, h3, h4, h5, img, iframe, and text alignment.
  • Social sharing icons should be shown if the merchant has enabled them in their theme options.

Nice-to-haves


Customer Account

Must-haves

  • All customer account links and features should only be displayed if the store has the customer accounts feature enabled, and if the store’s plan supports it. Use {{ store.customers_enabled }} to check this condition. For more details on all available customer Liquid variables, see the Liquid documentation.
  • When the customer is logged out, display links to:
    • Log in — using {{ customer_login_url }}
    • Create an account / Register — using {{ customer_registration_url }}
  • When the customer is logged in, display links to:
    • Their account overview — using {{ customer_account_url }}
    • Edit personal details — using {{ customer_edit_url }}
    • Edit addresses — using {{ customer.add_shipping_address_url }} and {{ customer.add_billing_address_url }}
    • Log out — using {{ customer.logout_url }}

Account page (logged-in state)

Must-haves

  • Display the customer’s name with a link to their account, and a logout link.
  • The /customer account page must show three main blocks: contact information, shipping addresses, and billing addresses.
  • The shipping and billing address blocks must include links to add, edit, delete, and mark an address as primary.
  • Display the customer’s order history. If no purchases have been made, show: “You have not made any purchases.” For each order in the list, display:
    • Order ID
    • Order status
    • Last updated date
    • Order total
    • A “Reorder” button
    • A list of ordered products showing quantity, subtotal, name, and variants. If a product no longer exists, display: “This product does not exist.”
    • An order summary block showing: shipping cost, subtotal, applied discounts, and order total.

Purchasing Process

Cart Page

Must-haves

  • A table of cart items, each showing: product image, name and variants, quantity (editable), price and discount if applicable, subtotal, and a remove button.
  • A shipping cost estimator form, if enabled in theme options — rendered using the Liquid tag {{ estimate_form }}.
  • A coupon code input field, if the store has promotional codes created — rendered using the Liquid tag {{ coupon_form }}.
  • An order summary table showing: subtotal, discounts, taxes, shipping cost, and total — using {{ order.subtotal }}, {{ order.discount }}, {{ order.tax }}, {{ order.shipping_cost }}, and {{ order.total }}.
  • A button to proceed to the checkout page — using the Liquid tag {{ order.checkout_url }} for the link.
  • If the cart is empty, display a message such as: “The shopping cart is currently empty. You can go back and start adding products.”

Checkout Page

Must-haves

  • A checkout form that supports custom fields — rendered using the Liquid tag {{ checkout_form }}. This tag already includes payment methods, shipping methods, and the button to proceed to the order review page.
  • An order summary table showing: subtotal, discounts, taxes, shipping cost, and total — using the same {{ order.* }} tags as the cart page.

Note: The checkout form rendered by {{ checkout_form }} comes with minimal built-in styles. Developers are responsible for styling it via app.css or any other CSS file by targeting standard HTML elements such as form, input, textarea, select, and radio buttons. Avoid writing styles that are too specific to checkout-only selectors — prefer global element styles that apply consistently across the whole theme.

Review Order Page

Must-haves

  • A table of ordered products, each showing: product image (no link), name and variants, quantity (not editable), price and discount if applicable, and subtotal. No delete option should be present.
  • An order summary table showing: subtotal, discounts, taxes, shipping cost, and total.
  • Display full order details, including shipping and billing information, contact details, and any additional information provided by the customer. Key Liquid tags from the order object include:
    • {{ order.shipping_address.formatted }} — formatted shipping address
    • {{ order.billing_address.formatted }} — formatted billing address
    • {{ order.email }} — customer email
    • {{ order.phone }} — customer phone number
    • {{ order.additional_information }} — any extra information provided at checkout
    • {{ order.custom_fields }} — custom fields collected during checkout

    For the full list of available order variables, refer to the Liquid documentation.

Order Success Page

Must-haves

  • A success message thanking the customer for their purchase. This can be personalized using {{ order.customer.name }} and should include the order number via {{ order.id }} — for example: “Thank you, [name]! Your order #[id] has been placed successfully.”
  • A confirmation note informing the customer that a confirmation email has been sent to their address — using {{ order.email }}.
  • Display full order details using the same order Liquid tags covered in the Review Order Page section above.
  • If customer login is optional or required in the store settings, display the customer create password form — rendered using the Liquid tag {{ customer_reset_password_form }}.
  • Display a product summary table listing the ordered items. This is standard convention in e-commerce and can either be shown by default or controlled via a theme option that the developer creates.

Pages & Page Categories

Must-haves

  • The page title must be displayed in an <h1> tag — using {{ page.name }} for static pages and {{ page_category.name }} for page categories (e.g. blog category listings).
  • The body of all static pages and page category pages must render the most common HTML tags correctly: ol, ul, li, strong, a, p, br, table, i, s, b, h2, h3, h4, h5, img, iframe, and text alignment.
  • All themes must include at least these three default page templates: Default, Post, and Blog.

Other

Theme Options

Must-haves

  • Use complete URLs for emails, social networks, and external links. Avoid building logic around usernames or account IDs.
  • If a theme option field is left empty by the merchant, the related code block must not render on the page.

Images

Must-haves

  • Product, category, and page images must be resized using the Liquid filter: {{ "image.jpg" | resize: "NxN" }} to optimize load times.
  • All images must have an alt attribute describing the image content. A title attribute can also be added when a tooltip on hover is desired, but it is not required.
  • If no image is available, a placeholder image must be shown in its place.

Nice-to-haves

  • Prefer resize over thumb for image resizing.
  • Consider lazy-loading images to improve performance on image-heavy pages. The native HTML loading="lazy" attribute is the recommended approach and works across all modern browsers. Third-party libraries like lazysizes are an option for broader legacy browser support, but are generally not necessary.

Translations

Must-haves

  • Punctuation like full stops (.) or colons (:) should sit outside of translation strings. Example: {% t 'Sort by' %}:
  • Themes should be fully translated into all of Jumpseller’s main supported languages before being published. Translations are managed at translate.jumpseller.com.

Note: Write translation strings with the end customer in mind. Merchant-facing helper strings (e.g. "This product has no image") do not need to be translated.

SEO

Must-haves

  • On the homepage: store name in <h1>, store description in <h2>, product names in <h3>.
  • On category pages: category name in <h1>, product names in <h2>, product descriptions in <h3>.
  • On product pages: product name in <h1>, section headings (e.g. description, reviews) in <h2>, any sub-headings within those sections in <h3>.
  • On static pages: page title in <h1>, content headings in <h2>, sub-headings in <h3>.
  • On page category pages (e.g. blog listings): page category name in <h1>, description if available in <h2>, individual post titles in <h3>.
  • On the contact page: page title in <h1>, description if available in <h2>, any additional section headings in <h3>.

Nice-to-haves

Follow general SEO web design best practices. Google provides two useful references:

Performance

Must-haves

  • Page load time should always be a consideration, especially for stores with large catalogs or many images.

Nice-to-haves

Start your journey with us!

Start your free 7-day trial. No credit card required.