# Slots

Slots are custom Vue components that you can inject into a storefront layout. A layout can include any number of `CUSTOM_SLOT` placeholders, positioned anywhere in its template — letting you add custom UI at any point within product, catalog, or category pages.

Sctructure example:

```
layouts/
└── catalog/
    └── example-catalog/
        ├── Main.vue
        └── slots/
            └── custom-bottom-bar/
                ├── CustomBottomBar.vue
                ├── server.ts
                └── client.ts
```

Slots live inside the `slots/` directory of a layout, organised by slot id. The slot id (directory name) is referenced in the layout's `Main.vue` via the `slot-id` attribute.

### How Slots Work <a href="#how-slots-work" id="how-slots-work"></a>

A layout component uses the `CUSTOM_SLOT` slot name to define where custom content can appear. The `slot-id` attribute connects the placeholder to a specific slot directory.

Layout with a custom slot:

```vue
<template>
  <div>
    <slot :name="Slot.PRODUCT_LIST" />
    <slot :name="Slot.CUSTOM_SLOT" slot-id="custom-bottom-bar" />
  </div>
</template>

<script setup lang="ts">
import { CatalogLayoutSlot as Slot } from '@lightspeed/crane-api';
</script>
```

The `slot-id="custom-bottom-bar"` value must match a directory name under `slots/` in the same layout.

The slot component itself is a regular Vue component, rendered both on the server (SSR) and on the client (hydration) — just like a section.

Slot component with entry points:

* **`CustomBottomBar.vue`**

```vue
<template>
  <div class="custom-bottom-bar">
    <button @click="handleClick">
      Go to Account
    </button>
  </div>
</template>

<script setup lang="ts">
const handleClick = () => {
  // Custom client-side logic
};
</script>
```

* **`server.ts`**

```typescript
import { createVueServerApp } from '@lightspeed/crane-api';
import CustomBottomBar from './CustomBottomBar.vue';
import { Content, Design } from '../../type.ts';

export default createVueServerApp<Content, Design>(CustomBottomBar);
```

* **`client.ts`**

```typescript
import { createVueClientApp } from '@lightspeed/crane-api';
import CustomBottomBar from './CustomBottomBar.vue';
import { Content, Design } from '../../type.ts';

export default createVueClientApp<Content, Design>(CustomBottomBar);
```

{% hint style="info" %}
**Inherited settings**

Slots inherit their content and design types from the parent layout's `type.ts`. The `Content` and `Design` types are imported from `../../type.ts` relative to the slot directory.
{% endhint %}

### Slot Files <a href="#slot-files" id="slot-files"></a>

Each slot directory must contain the following files:

| File                   | Required | Description                                        |
| ---------------------- | -------- | -------------------------------------------------- |
| Vue component (`.vue`) | Yes      | The slot's UI component                            |
| `server.ts`            | Yes      | Server-side entry point using `createVueServerApp` |
| `client.ts`            | Yes      | Client-side entry point using `createVueClientApp` |

Both entry points follow the same pattern as section entry points. Refer to the section documentation for details:

* [Server](/site-themes/develop-site-themes/sections/server.md)
* [Client](/site-themes/develop-site-themes/sections/client.md)

### Connecting a Slot to a Layout <a href="#connecting-a-slot-to-a-layout" id="connecting-a-slot-to-a-layout"></a>

To add a custom slot to a layout:

1. Create a directory under `slots/` in your layout (e.g. `slots/my-widget/`).
2. Add a Vue component, `server.ts`, and `client.ts` to the directory.
3. In the layout's `Main.vue`, use `<slot :name="Slot.CUSTOM_SLOT" slot-id="my-widget" />` where the `slot-id` matches the directory name.

{% hint style="info" %}
**Multiple slots**

You can add multiple custom slots to a single layout by creating multiple directories under `slots/` and referencing each one with a separate `<slot>` element using a different `slot-id`.
{% endhint %}

### Validation Errors <a href="#validation-errors" id="validation-errors"></a>

Crane validates your slots during the build step. Below are the errors you may encounter and how to resolve them.

#### Slot Errors <a href="#slot-errors" id="slot-errors"></a>

| Error                                                                     | Cause                                                     | Resolution                                                                    |
| ------------------------------------------------------------------------- | --------------------------------------------------------- | ----------------------------------------------------------------------------- |
| `Store layout sectionId "..." must be one of: catalog, category, product` | Slot is placed under an invalid storefront page directory | Move the slot's parent layout under `product/`, `catalog/`, or `category/`    |
| `Size of individual server file [...] must not exceed threshold [...]`    | The slot's server bundle exceeds 500 KB (uncompressed)    | Reduce the server bundle size — simplify the component or extract shared code |
| `Cannot find client entrypoint file for slot ...`                         | The slot directory is missing a `client.ts` file          | Add a `client.ts` entry point to the slot directory                           |

#### Schema Errors <a href="#schema-errors" id="schema-errors"></a>

| Error                           | Cause                                      | Resolution                                  |
| ------------------------------- | ------------------------------------------ | ------------------------------------------- |
| `Unrecognized key(s) in object` | Extra properties in the slot configuration | Remove properties not defined in the schema |

{% hint style="warning" %}
Server Bundle Size Limit

Each slot's server bundle must not exceed **500 KB** (uncompressed). Oversized bundles will cause a validation error during the build step.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ecwid.com/site-themes/develop-site-themes/templates/layouts/slots.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
