← Files KnockARCHIVED FILE

skills/knock-cli/rules/knock-directory-structure.md

7.83 KB · Oct 3, 2026 · 06:18 UTC

↓ Download file

---
title: Knock directory structure
description: Understanding the knock directory layout, configuration files, and resource organization
tags:
  - knock
  - cli
  - directory-structure
  - configuration
  - knock-json
  - workflows
  - layouts
category: knock-cli
last_updated: 2026-08-12
---

# Knock directory structure

## Project configuration

### The knock.json file

Running `knock init` creates a `knock.json` file in your project root. This file configures where Knock resources are stored.

**Basic structure:**

```json
{
  "knockDir": "./knock"
}
```

**Configuration options:**

| Property | Description | Default |
|----------|-------------|---------|
| `knockDir` | Path to the directory containing Knock resources | `./knock` |

The `knockDir` is relative to the location of `knock.json`. All CLI operations use this directory as the root for reading and writing resources.

## Directory layout

The knock directory contains subdirectories for each resource type:

```
knock/
├── workflows/                    # Workflow definitions
│   ├── workflow.schema.json      # JSON Schema for validation
│   └── {workflow-key}/           # One directory per workflow
│       ├── workflow.json         # Main workflow definition
│       └── {step-ref}/           # Channel step content (optional)
│           └── ...               # Template files
│
├── email-layouts/                # Email layout templates
│   └── {layout-key}/
│       ├── layout.json           # Layout configuration
│       └── ...                   # Layout template files
│
├── guides/                       # In-app guides (lifecycle messaging)
│   └── {guide-key}/
│       └── guide.json            # Guide definition and content
│
├── message-types/                # Message type schemas for guides
│   └── {message-type-key}/
│       ├── message_type.json     # Schema and metadata
│       └── preview.html          # Optional; Liquid template for dashboard preview
│
├── translations/                 # Translation files
│   └── {locale}/
│       └── ...                   # Translation JSON files
│
├── partials/                     # Reusable template partials
│   └── {partial-key}/
│       └── ...                   # Partial template files
│
└── commits/                      # Commit history (managed by CLI)
```

## Workflow structure

Each workflow lives in its own directory under `workflows/`:

```
workflows/{workflow-key}/
├── workflow.json                 # Main workflow definition
└── {step-ref}/                   # Directory per channel step (optional)
    └── ...                       # Template content files
```

### workflow.json

The main workflow definition file contains:

```json
{
  "name": "Order Confirmation",
  "description": "Sends order confirmation notifications",
  "categories": ["transactional", "orders"],
  "steps": [
    {
      "ref": "email-step",
      "type": "email",
      "template": {
        "subject": "Order #{{data.order_id}} confirmed",
        "visual_blocks@": "email-step/visual_blocks.json"
      }
    }
  ]
}
```

**Key fields:**

| Field | Description |
|-------|-------------|
| `name` | Display name for the workflow |
| `description` | Optional description |
| `categories` | Optional array of category tags |
| `steps` | Array of workflow steps |

### Step directories

Channel steps (email, SMS, push, etc.) can have their template content extracted into separate files within a step directory:

```
workflows/order-confirmation/
├── workflow.json
└── email-step/
    ├── visual_blocks.json        # Email visual blocks structure
    └── visual_blocks/
        ├── 1.content.md          # First block content
        ├── 2.content.md          # Second block content
        └── ...
```

**When step directories exist:**
- Channel steps with extracted template content
- Complex templates that benefit from separate files

**When step directories don't exist:**
- Function steps (delay, batch, branch, fetch, etc.) never have directories
- Simple templates with inline content

## Email layouts

Email layouts define reusable structure for email templates:

```
email-layouts/{layout-key}/
├── layout.json                   # Layout configuration
├── html_layout.html              # HTML layout template (optional)
└── ...                           # Additional layout files
```

### layout.json

```json
{
  "name": "Default Layout",
  "html_layout@": "html_layout.html",
  "text_layout": "{{ content }}",
  "footer_links": [
    {
      "label": "Unsubscribe",
      "url": "{{ unsubscribe_url }}"
    }
  ]
}
```

## Guides

Guides are in-app UI components for lifecycle messaging (banners, modals, announcements). Each guide lives in its own directory:

```
guides/{guide-key}/
└── guide.json                    # Guide definition with steps and content
```

### guide.json

A guide contains a `name` and a `steps` array. Each step references a message type via `schema_key` and `schema_variant_key`, with content in `values`. See the guides and message types rule file for full details.

## Message types

Message types define the schema for guide content. They live under `message-types/`:

```
message-types/{message-type-key}/
├── message_type.json             # Schema with variants and fields
└── preview.html                  # Optional; Liquid template for dashboard preview
```

### message_type.json

The message type schema defines `name`, `description`, `icon_name`, and `variants`. Each variant has `key`, `name`, and `fields`. The `preview@` field references the preview HTML file. See the guides and message types rule file for schema details.

## File path references

Knock uses the `@` suffix convention to indicate file path references:

```json
{
  "content@": "visual_blocks/1.content.md",
  "html_body@": "body.html",
  "visual_blocks@": "email-step/visual_blocks.json"
}
```

**Path resolution rules:**

1. Paths are **relative to the file containing the reference**
2. In `workflow.json` (at workflow root): paths start from the workflow directory
3. In `visual_blocks.json` (inside step directory): paths are relative to that step directory

**Example:**

```
workflows/my-workflow/
├── workflow.json                 # Uses: "visual_blocks@": "email-step/visual_blocks.json"
└── email-step/
    ├── visual_blocks.json        # Uses: "content@": "visual_blocks/1.content.md"
    └── visual_blocks/
        └── 1.content.md
```

**Common mistake:** Doubling the step directory path. If you're in `email-step/visual_blocks.json`, use `visual_blocks/1.content.md`, NOT `email-step/visual_blocks/1.content.md`.

## JSON Schema

The `workflows/workflow.schema.json` file provides validation for workflow definitions. Reference this schema when:

- Creating or modifying templates
- Working with specific channel types
- Encountering validation errors
- Adding function steps

## Resource identification

Resources are identified by their directory name (the key):

| Resource Type | Key Location | Example |
|---------------|--------------|---------|
| Workflow | Directory name under `workflows/` | `workflows/order-confirmation/` → key: `order-confirmation` |
| Email Layout | Directory name under `email-layouts/` | `email-layouts/default/` → key: `default` |
| Guide | Directory name under `guides/` | `guides/welcome-modal/` → key: `welcome-modal` |
| Message Type | Directory name under `message-types/` | `message-types/banner/` → key: `banner` |
| Partial | Directory name under `partials/` | `partials/footer/` → key: `footer` |

This key is used in CLI commands:

```bash
knock workflow push order-confirmation
knock layout push default
knock guide push welcome-modal
knock message-type push banner
```

SHA-256: 75fb66139eceb14a70e2a0d1f92c33964331982b4044f4a9e2036e36573553ee