> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.knapsack.cloud/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.knapsack.cloud/_mcp/server.

# Handlebars

Knapsack for Handlebars works by scanning your specified Handlebars code locations and automatically discovering reusable components, making them instantly available in your design system.

**Why This Approach:**

* ⚡ **Zero Manual Work** - Knapsack finds and configures your components automatically
* 🔄 **Always Current** - Your documentation stays in sync with code changes
* 🎯 **Intelligent** - Understands different export patterns and component structures
* 🚀 **Scale Effortlessly** - Handle hundreds of components without individual setup

### Requirements

* **Handlebars templates** - Templates must be in `.hbs` or `.handlebars` format
* **JavaScript/TypeScript exports** - For template data and helpers

***

## Install

```bash
npm install @knapsack/renderer-hbs
```

## Configure

**Minimal Setup**
The simplest configuration requires just specifying where your Handlebars components are located:

```js
// knapsack.config.js
const { KnapsackHbsRenderer } = require('@knapsack/renderer-hbs');

module.exports = configureKnapsack({
  templateRenderers: [
    new KnapsackHbsRenderer({
      codeSrcs: [
        { path: '@my-design-system/handlebars/*' },
      ],
    }),
  ],
};
```

**Full Configuration Example**
Here's a comprehensive example showing all available options:

```js
// knapsack.config.js
const path = require('path');
const fs = require('fs');
const { KnapsackHbsRenderer } = require('@knapsack/renderer-handlebars');

module.exports = configureKnapsack({
  templateRenderers: [
    new KnapsackHbsRenderer({
      // Discover your Handlebars templates/partials
      codeSrcs: [
        // Local templates
        { path: './src/templates/**/*.hbs' },
        { path: './src/partials/**/*.hbs' },

        // Example: pull templates from a package
        { path: '@my-design-system/handlebars/*' },
      ],

      // Add custom helpers/partials programmatically
      alterHandlebars(handlebars) {
        // Helpers
        handlebars.registerHelper('uppercase', (str) =>
          String(str ?? '').toUpperCase(),
        );
        handlebars.registerHelper('eq', (a, b) => a === b);

        // Partials (inline or from files)
        handlebars.registerPartial('badge', '<span class="badge">{{text}}</span>');

        const buttonPartialPath = path.resolve(
          __dirname,
          'src/partials/button.hbs',
        );
        if (fs.existsSync(buttonPartialPath)) {
          handlebars.registerPartial(
            'button',
            fs.readFileSync(buttonPartialPath, 'utf8'),
          );
        }
      },
    }),
  ],
});
```

### Code Sources

The **codeSrcs** array tells Knapsack where to find your Handlebars components and how to process them. The renderer will scan these paths, find Handlebars component exports, and make them available in the Knapsack UI for documentation and demos.

##### Local Components

Paths are relative to *knapsack.config.js*

```js
codeSrcs: [
  // Specific directory
  { path: './src/components/**/*.hbs' },

  // Multiple file extensions (Handlebars + helpers/partials in JS/TS)
  { path: './src/ui/**/*.{hbs,js,ts}' },

  // Specific component types
  { path: './src/components/atoms/*.hbs' },
  { path: './src/components/molecules/*.hbs' },
];
```

##### External Libraries

Ensure that any external library is included in your package dependencies

```js
codeSrcs: [
  // Entire package (Handlebars templates)
  { path: '@my-org/handlebars-design-system' },
  { path: '@my-org/hbs-theme' },

  // Package sub-paths
  { path: '@my-org/handlebars-design-system/components/*' },
  { path: '@my-org/design-system/templates/*' },
];
```

##### Smart Filtering

Use filters to control exactly which components are discovered:

```js
codeSrcs: [
  {
    path: './src/**/*.hbs',
    filter: (filePath) => {
      // Only include template components, exclude utilities and tests
      return (
        filePath.includes('/components/') &&
        !filePath.includes('.test.') &&
        !filePath.includes('.stories.')
      );
    },
  },
  {
    path: '@my-org/handlebars-library/*',
    filter: (filePath) => {
      // Exclude non-template or internal files from the package
      const excludedPaths = [
        '@my-org/handlebars-library/index',
        '@my-org/handlebars-library/internal',
        '@my-org/handlebars-library/utils',
      ];
      return !excludedPaths.some((excluded) => filePath.includes(excluded));
    },
  },
];
```

### Alter Handlebars

This enables you to register custom partials, helpers, and other modifications to the Handlebars environment, enhancing the flexibility and power of your templates. In addition to registering partials, you can use the `alterHandleBars` function to register helpers, set custom delimiters, or perform other runtime customizations. Refer to the [Handlebars Runtime API documentation](https://handlebarsjs.com/api-reference/runtime.html#handlebars-registerpartial-name-partial) for more details on the available methods and their usage.

By leveraging these customization capabilities, you can tailor the Handlebars runtime to meet the specific needs of your project, ensuring a powerful and flexible templating environment within Knapsack.

##### Example Configuration

The following example demonstrates how to configure Knapsack with a custom Handlebars renderer and register a partial named foo. In this example, the `alterHandleBars` function registers a partial named `badge` with the template `<span class="badge">{{text}}</span>`. This partial can then be used in other Handlebars templates within your Knapsack project.

```js
module.exports = configureKnapsack({
  templateRenderers: [
    new KnapsackHbsRenderer({
      alterHandleBars: (handlebars) => {
        handlebars.registerPartial('badge', '<span class="badge">{{text}}</span>');
      }
    })
  ]
})
```

##### Using Registered Partials

Once a partial is registered, you can use it in your templates by referencing its name with the partial syntax `{{> partialName}}`. For example, to use the `badge` partial:

```handlebars
{{> badge text="Hello, world!" }}
```