Deep dive into theme project structure

circle-info

We highly recommend setting up a working example theme before jumping into this guide: Quickstart with a Site theme example

Congratulations on getting a working template example!

Now that you have a theme project, follow us through this article, and you'll end up with an understanding of how theme apps work and which parts require your dev attention.

Let's dive into its structure to answer the following questions:

  • Which files define user settings and default configurations?

  • Where do you write the actual storefront code?

  • How are user settings imported into the storefront?

How to make themes work

Instant Site theme is a schema-driven rendering system based on Vue.jsarrow-up-right and TypeScriptarrow-up-right. So as a developer, you need to:

  • Define user settings so users can customize your theme for their business needs.

  • Build storefront blocks called sections.

  • Combine several blocks into a theme.

Each of these functionalities lies within its own folder or specific files. Therefore, you need to work on specific files to extend the basic starting example into a highly customized theme.

To understand which files and folders you need, let's cover the basic folder structure of the project.

Learn folder structure

You can find the following directories in any theme project:

  • templates/: This folder holds theme files that define the structure of your site. Theme files in this folder do not contain the actual HTML code of the blocks, but rather the configuration (the "DNA") that tells Ecwid the order in which sections should be loaded on different website pages.

  • sections/: This folder contains building blocks of your theme. Every folder inside represents a drag-and-drop section in the Store Editor. They are self-contained, meaning they hold their own logic, styles, and settings schema.

  • headers/ and footers/: These two folders define global <head> and <footer> sections that appear on every page. They follow the same file structure as sections/, but are assigned globally in the configuration.ts file.

  • layouts/: Unlike sections (stacked one after another), layouts wrap the entire content area of dynamic pages (like a Product Details page). They use special placeholders called "slots" to determine where the platform should inject dynamic content (like the product price, description, and "Add to Cart" button).

  • shared/: To avoid repeating code, any logic (composables) or UI (components) used by more than one section is stored here. For example, if five different sections use a slider, the slider logic resides in shared/composables/useCarousel.ts.

  • dist/, node_modules/, preview/: System folders required for building, running, and previewing the theme. Treat these as generated or dependency artifacts. Do not modify them.

Now that the folders are covered, we can jump into specific files.

Learn main project files

The following files are included in basically any theme project, so it's important to understand what they do:

- MySection.vue

This is the visual implementation of the section. Visitors see this content on the website, and store owner's settings apply to it.

This file is written as a Vue Single File Component. It contains the template, styles, and component logic, but does not define any "user settings" (design/content settings available to the store owner).

What it does:

  • Reads resolved content values

  • Reads resolved design values

  • Renders markup accordingly

What it does not do:

  • Declare schemas

  • Fetch data on the storefront

  • Decide editor behavior

circle-info

Think of this file as a pure renderer. The configuration is already resolved when it runs.

Learn more about building section Vue files:

section-name.vuechevron-right

- server.ts

This file is the server-side entrypoint for the section.

Purpose:

  • Register the section for server-side rendering

  • Produce initial HTML

Characteristics:

  • Runs in a Node environment

  • Uses the section’s Vue component

  • Is generic and usually very small

circle-info

Every section that renders on the server must have this file.

- client.ts

This file is the browser entrypoint for the section.

Purpose:

  • Attach interactivity

  • Enhance or hydrate server-rendered markup

Characteristics:

  • Runs in the browser

  • Uses the same Vue component as the server

  • Assumes HTML already exists

circle-info

If your section has no interactivity, this file may be minimal — but the contract still exists.

- type.ts

This file connects schemas to rendering code.

Purpose:

  • Derive TypeScript types from schemas

  • Ensure rendering stays in sync with configuration

Typical responsibilities:

  • Export Content type

  • Export Design type

circle-info

This prevents schema drift. If the schema changes, TypeScript forces the UI to update.

- settings/

This directory defines what can be customized. Design and content settings defined in the files stored inside will be available to the store owner in the Ecwid admin UI.

circle-info

These files are schemas, not implementations.

- settings/content.ts

Defines editable content. With these settings, store owners can tailor texts, images, etc., to their business needs.

For example, you can define customizable:

  • Texts

  • Images

  • Buttons

circle-info

If some section content (like a text) is not declared as a setting here, it cannot be edited.

Learn more about available content settings:

content.tschevron-right

- settings/design.ts

Defines design controls. With these, store owners can apply changes to the theme/section appearance on their website.

Examples:

  • Colors

  • Typography

  • Spacing

  • Visibility toggles

  • Variants

circle-info

This exposes design tokens, not raw CSS.

Learn more about available design settings:

design.tschevron-right

- settings/translations.ts

Defines human-readable labels and descriptions for schemas. Any texts shown in the Ecwid admin UI can have several translations, and this file sets these.

Used by:

  • Editor UI

  • Schema metadata

circle-info

All schema labels must be translated to all specified languages.

Learn more about adding translations to section settings:

translations.tschevron-right

- showcases/

Showcases define example instances of a section. This folder is optional.

Purpose:

  • Provide preview data

  • Show how the section looks with real values

  • Populate galleries or demos

circle-info

Showcases are not defaults. They are merely examples shown when users select which section to add in the Ecwid admin UI.

Learn more about section showcases:

showcases/1.tschevron-right

- assets/

Contains assets used by the section, for example:

  • Default images

  • Preview images

  • Icons

Assets may be:

  • Referenced by schemas (defaults)

  • Used by showcases

  • Imported by the Vue component

Schema for an example theme

Use this example schema as a helping tool to ensure your project has all of the required files to function properly.

Project files that require dev attention

Now that you know what specific folders and files do, you can start building your own sections and theme. And any theme technically is an ordered list of sections.

Therefore, when starting from an example theme, we recommend building sections first. New sections should look like this:

Use example sections as a carcass to develop the section you need:

  • Add new example sections with the npx @lightspeed/crane@latest init --section section-name CLI command.

    • Build the main Vue file - add your content and design. Think about its content - what users should be able to change here.

    • Define all settings that should be available to users in TypeScript files in the /settings/ folder.

    • If you have any default images for section content or previews, put them in /assets/ and /showcases/ folders.

  • Build TypeScript theme files using both created sections and default sections.

  • Make sure all service files are still in place, then build and deploy theme to your dev store to check how it works.

Last updated

Was this helpful?