---
title: "Predefined Templates"
description: "When opening an editor without any template, user can choose between starting from scratch of pick predefined template."
url: https://docs.topol.io/email-editor/guide/premade-templates-in-editor.html
---

# Premade templates in the editor

**Premade templates let users start from a designed template instead of an empty canvas.**

## Enabling premade templates

To activate the premade template picker, set the following option in your `TOPOL_OPTIONS` configuration:

```ts
premadeTemplates: true,
```

Once enabled, users who open the editor on an empty template are presented with two options:

-   Start from predefined template
-   Design from scratch

![Predefined template picker start](https://docs.topol.io/premade-templates-start.png)

Selecting the predefined template option opens a Premade Template Modal Picker directly inside the editor.

![Predefined template modal picker](https://docs.topol.io/premade-templates-picker.jpeg)

The Premade Template Modal Picker displays a selection of ready-made email templates provided by Topol. These templates are hosted by Topol and are immediately available to use without further configuration.

The picker can also filter templates by **categories** or **keywords**. Those filters appear only when the matching API endpoints are set in your `TOPOL_OPTIONS.api` configuration for listing [categories](https://docs.topol.io/email-editor/guide/premade-templates-in-editor.html#list-categories) and [keywords](https://docs.topol.io/email-editor/guide/premade-templates-in-editor.html#list-keywords). Setting either endpoint to an **empty string** disables the corresponding filter.

## Picker options

The optional `premadeTemplatesOptions` object controls two elements of the picker interface:

```ts
premadeTemplatesOptions: {
  hideSearch: true,  // hides the search input in the template list
  showDelete: true,  // shows the Delete button on a template's detail view
},
```

Both keys are optional booleans and default to off. `showDelete` is what surfaces the Delete button that calls the [Remove Template](#remove-template) endpoint, so custom template libraries that support deletion need it set.

## Load custom premade templates

Alongside the default Topol templates, your own template library can be served from your backend, which puts brand-specific or client-specific templates directly in the editor.

To do this, implement the following API endpoints.

> **WARNING**
>
> **Before implementing the endpoints, check [how to work with API endpoints.](https://docs.topol.io/email-editor/guide/how-to-work-with-your-api.html)**

### List Templates

Called to retrieve a paginated list of available templates.

**Request**

-   URL: `/{API.PREMADE_TEMPLATES}`
-   Method: `GET`
-   params:
    -   `per_page` (integer) - number of templates per page, always sent, starts at 25
    -   `current_page` (integer) - page number, always sent, starts at 1
    -   `categories` (array) - category IDs to filter by
    -   `keywords` (array) - keyword IDs to filter by
    -   `search` (string) - search for templates by name

`per_page` and `current_page` are sent on every request, so your endpoint does not need defaults for them. The remaining three are sent only when a filter or search is active.

**Expected Response:**

```json
{
  "success": true,
  "data": {
    "data": [
      {
        "id": 1,
        "name": "Example template",
        "type": "FREE",
        "img_thumb_url": "example.com/img-thumb-url",
        "category_id": 1,
        "description": "Example description",
        "keywords": [
          {
            "id": 1,
            "keyword": "marketing",
            "slug": "marketing",
            "created_at": "2023-01-01T00:00:00.000000Z",
            "updated_at": "2023-01-01T00:00:00.000000Z",
            "pivot": {
              "premade_template_id": 1,
              "premade_template_keyword_id": 1
            }
          }
        ],
        "created_at": "2023-01-01T00:00:00.000000Z",
        "updated_at": "2023-01-01T00:00:00.000000Z"
      }
    ],
    "total_records": 150,
    "current_page": 1,
    "per_page": 25,
    "next_page": 2,
    "prev_page": null,
    "last_page": 6
  }
}
```

Of the pagination fields, only `last_page` is read by the editor, where it decides whether the Load more button appears. The others are accepted and ignored, so they are safe to include for your own use. Each template entry needs `id` and `img_thumb_url` for the list to render.

### List Template

Retrieves full content (HTML + JSON) of the selected template.

-   URL: `/{API.PREMADE_TEMPLATES}/{template-id}`
-   Method: `GET`

**Response:**

```json
{
  "success": true,
  "data": {
    "id": 1,
    "name": "Example template",
    "type": "FREE",
    "html": "<b>example html </b>",
    "json": "{\"example\": \"json\"}",
    "category_id": null,
    "order": 1,
    "description": null,
    "visible": 1,
    "created_at": "2023-01-01T00:00:00.000000Z",
    "updated_at": "2023-01-01T00:00:00.000000Z",
    "image_path": "/img/templates/1.jpg",
    "image_thumb_path": "/img/templates/1_thumb.jpg",
    "category": null,
    "keywords": []
  }
}
```

The editor reads only `html` and `json` from this response. `json` must be a JSON-encoded **string**, as shown above, because the editor parses it before loading the template.

### List Categories

Calling this endpoint will enable a built-in feature for filtering templates by categories and populate it with relevant data.

-   URL: `/{API.PREMADE_TEMPLATE_CATEGORIES}`
-   Method: `GET`

**Response:**

Successful response will look like this:

```json
{
  "success": true,
  "data": [
    {
      "id": 1,
      "name": "Business",
      "value": "business"
    },
    {
      "id": 2,
      "name": "E-commerce",
      "value": "e-commerce"
    }
  ]
}
```

### List Keywords

Calling this endpoint will enable a built-in feature for filtering templates by keywords and populate it with relevant data.

-   URL: `/{API.PREMADE_TEMPLATES_KEYWORDS}`
-   Method: `GET`

**Response:**

Successful response will look like this:

```json
{
  "success": true,
  "data": [
    {
      "id": 1,
      "name": "sale/discount",
      "value": "salediscount"
    },
    {
      "id": 2,
      "name": "autumn",
      "value": "autumn"
    }
  ]
}
```

### Remove Template

Deletes a template from your custom source. The Delete button that calls this endpoint appears only when `premadeTemplatesOptions.showDelete` is set (see [Picker options](#picker-options)).

-   URL: `/{API.PREMADE_TEMPLATES}/{templateId}`
-   Method: `DELETE`

**Expected response:**

```json
{
  "success": true
}
```
