Skip to content
On this page

Project structure ​

A folder-by-folder tour of souk-theme/. Read once, refer back when you need to remember "where do X live?"

souk-theme/
├── app.vue                  Root component. Renders global Header/Footer + the active page.
├── error.vue                Renders when Nuxt catches a route error.
├── nuxt.config.ts           Nuxt configuration — runtime config, modules, build settings.
├── tailwind.config.js       Tailwind setup — maps utility classes to design tokens.
├── tsconfig.json            TypeScript config.
├── package.json             Dependencies + npm scripts.
├── Dockerfile               Production container build (for the dev/prod Node server).
├── README.md                Quick start (you're past this).
├── DEPLOY.md                Deploy notes for the team.
├── .env.example             Template for local env vars. Copy to .env.
│
├── components/              All Vue components.
│   ├── sections/            ← where you spend 95% of your time.
│   │   ├── Banner/
│   │   ├── Heading/
│   │   ├── Header/
│   │   ├── Footer/
│   │   ├── ProductGrid/
│   │   └── ... (50+ sections)
│   ├── TemplateSections.vue The renderer that walks templates[page] and instantiates each section.
│   ├── ProductCard.vue      Shared product-card UI used by grid sections.
│   └── ... (other shared UI components)
│
├── pages/                   Nuxt routes — one file per public URL.
│   ├── index.vue            /              (home)
│   ├── shop.vue             /shop          (catalog)
│   ├── cart/                /cart          (cart pages)
│   ├── wishlist.vue         /wishlist
│   ├── products/[slug].vue  /products/:slug
│   ├── collections/         /collections, /collections/:slug
│   ├── blog.vue             /blog
│   ├── posts/[slug].vue     /posts/:slug
│   ├── pages/[slug].vue     /pages/:slug   (CMS pages)
│   ├── thanks.vue           /thanks        (order confirmation)
│   ├── search.vue           /search
│   └── account/             /account, /account/orders, etc.
│
├── plugins/                 Boot-time wiring.
│   ├── init.ts              The big one — fetches the active theme on SSR,
│   │                        sets up Pinia state, decides builder mode.
│   ├── http.ts              Axios client. Resolves the auth token from
│   │                        URL/cookie/env (see Getting started → Connecting to a store).
│   ├── storeino.ts          The `$storeino` API client used in data-driven sections.
│   ├── bridge.client.ts     PostMessage bridge to the builder. Only matters in builder mode.
│   ├── theme-vars.client.ts Emits the merchant's tokens as :root CSS variables.
│   ├── events.client.ts     Cart / wishlist event bus.
│   ├── pixels.client.ts     Facebook/Google/TikTok pixel boot.
│   ├── page-view.client.ts  Pageview tracking.
│   ├── animations.client.ts Intersection-observer-driven entrance animations.
│   ├── currency-modal.client.ts  First-visit currency picker.
│   ├── resize-handles.client.ts  Builder-mode resize handles on images.
│   ├── sanitize-payload.server.ts  SSR safety: scrub null-prototype objects.
│   └── tools.ts             Misc helpers exposed on $tools.
│
├── composables/             Reusable hooks. Most you'll touch:
│   ├── useT.ts              Translate a value (string or locale map).
│   ├── useStyles.ts         Pick up merchant style edits per element.
│   ├── useEditable.ts       Click-to-edit text in builder mode.
│   ├── useThemeStore         Alias for the Pinia theme store.
│   └── use*Context.ts       Per-page data adapters (CartContext, BlogContext, ...).
│                            Used by page-aware sections to read what page they're on.
│
├── stores/                  Pinia stores.
│   ├── theme.ts             The theme document — sections, templates, tokens.
│   │                        Mutated by patches from the builder.
│   └── main.ts              Shopper state — cart, wishlist, language, currency.
│
├── utils/                   Pure helpers (no Vue, no Pinia).
│   ├── sectionRegistry.ts   Auto-discovers components/sections/* at boot.
│   ├── elementRegistry.ts   Same idea for sub-element components.
│   ├── initializePixels.ts  Pixel boot helper.
│   └── storeinoApp.ts       Internal init helper.
│
├── types/                   Shared TypeScript types.
│   └── section.ts           SectionInstance, SectionManifest, ValueSchema, etc.
│
├── public/                  Static assets served at /...
│   ├── sections/            ← Auto-generated. Don't edit by hand.
│   │   └── manifest-index.json
│   ├── elements/
│   └── templates/
│
├── server/                  Nitro server routes + middleware (Nuxt's server side).
│   └── middleware/          Per-request middleware (auth header reshaping, etc.).
│
├── assets/                  Source assets bundled by Vite.
│   └── css/                 main.css (Tailwind imports + token CSS).
│
├── scripts/                 Build / deploy / maintenance Node scripts.
│   ├── build-manifest-index.mjs     Regenerates public/sections/manifest-index.json.
│   ├── build-chrome-bundles.mjs     Builds Header/Footer bundles for the builder.
│   ├── build-global-bundles.mjs     Builds the global-slot manifest.
│   ├── seed-registry.mjs            Pushes the section catalog to api-stores.
│   ├── upload-cdn.mjs               Uploads .output/public/ to BunnyCDN.
│   ├── swap-brand-thumbs.mjs        Maintenance: refresh thumbnail URLs.
│   └── patch-broken-esm.mjs         Postinstall workaround for one broken dep.
│
└── docs/                    Internal team docs (markdown, not the public site).

Where you spend your time ​

For section work, you'll mostly touch:

FolderWhen
components/sections/<NewSection>/Every section you build lives here.
composables/Read useT, useStyles, useEditable for reference. Rarely add new ones.
components/ProductCard.vueRead if you're building a product-data section. Don't modify without checking with Abdel — it's shared.
assets/css/main.cssAlmost never. Global tweaks only. Section CSS lives inline as Tailwind classes.

Where you almost never go ​

FolderWhy
plugins/Boot infrastructure. Modifying these affects every page.
stores/theme.tsThe shape of the theme document. Modifying it touches the builder + api-stores model.
scripts/Deploy machinery. Run them via npm run build / npm run deploy, don't edit.
server/middleware/Per-request SSR hooks. Owned by infra.
nuxt.config.tsBoot config. Adding a new dependency that needs Nuxt config is the only legitimate reason.
types/section.tsThe SectionInstance / SectionManifest shapes. If you need to add a new field type (e.g. gradient), this is where it goes — but ping Abdel first because the builder also needs the matching editor.

How sections wire into pages ​

This is the single most-asked structural question:

pages/index.vue                 (the home route)
  └─ <TemplateSections template="home" />
       └─ Reads themeStore.theme.config.templates.home   (an array of SectionInstance)
            └─ For each instance:
                  resolveSection(instance.type)          (looks up the component)
                  → renders <YourSection :config="instance.values" />

The chain is:

  1. Page decides which template slot to render (home, shop, product, ...).
  2. TemplateSections walks the array of section instances for that slot.
  3. Section registry (utils/sectionRegistry.ts) returns your component for each type.
  4. Your component renders, receiving the merchant-saved values as config.

You write code at step 4. Steps 1-3 are framework — already done.

Adding a new file: where to put it ​

You're adding...Goes in...
A new sectioncomponents/sections/<TypeName>/{index.vue, manifest.json}
A shared UI piece used by multiple sectionscomponents/<Name>.vue (e.g. how ProductCard.vue is used by ProductGrid, ProductRelated, etc.)
A new page routepages/<route>.vue — but check first; new public routes change the SEO surface and usually need product approval
A new composablecomposables/use<Name>.ts — only if it's genuinely reusable; one-off helpers go inline in the section
A new pure helperutils/<name>.ts
A new TypeScript type used by sectionstypes/section.ts if section-related, otherwise alongside the file that uses it

A note on "core" files ​

You may have seen the legacy docs talk about @storeino/template-core-v2 — a separately-installed package containing plugins and utils. Souk-theme does NOT use that package. Plugins live directly in plugins/, helpers in utils/. Easier to read, easier to debug, no version-skew between theme and the shared package. Ignore any reference to template-core-v2.

Released under the MIT License.