> For the complete documentation index, see [llms.txt](https://docs.realmacsoftware.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.realmacsoftware.com/elements/api-reference/components/hooks.js.md).

# Hooks.js

Hooks provide a powerful way to extend your components by manipulating properties before they are applied within templates.

## Component Lifecycle

The typical flow of a component follows this sequence:

```
properties.json → hooks.js → template.html
```

1. **Properties** define the UI controls and their values
2. **Hooks** process and transform those values
3. **Templates** render the final HTML output

## Creating a Transform Hook

To use a transform hook, create a `hooks.js` file in the root of your component:

```javascript
const transformHook = (rw) => {
    // Access properties from UI controls
    const { title, isVisible } = rw.props;
    
    // Transform and pass data to templates
    rw.setProps({
        message: `Hello, ${title}!`,
        displayClass: isVisible ? 'block' : 'hidden'
    });
};

exports.transformHook = transformHook;
```

{% hint style="info" %}
Each component has its own unique `hooks.js` file. To share code across multiple components, we recommend using a build system or creating a script to merge and copy JS files to each component.
{% endhint %}

## The `rw` Object

The `rw` object is passed to your transform hook and provides access to component data and helper functions.

### Available Data

| Property                                                                                                     | Description                                        |
| ------------------------------------------------------------------------------------------------------------ | -------------------------------------------------- |
| [`rw.props`](/elements/api-reference/components/hooks.js/available-data/rw.props.md)                         | UI control values from properties.json             |
| [`rw.responsiveProps`](/elements/api-reference/components/hooks.js/available-data/rw.getresponsivevalues.md) | Responsive property values by breakpoint           |
| [`rw.collections`](/elements/api-reference/components/hooks.js/available-data/rw.collections.md)             | Component collections data                         |
| [`rw.project`](/elements/api-reference/components/hooks.js/available-data/rw.project.md)                     | Project-level data (title, mode, siteUrl, etc.)    |
| [`rw.system`](/elements/api-reference/components/hooks.js/available-data/rw.system.md)                       | Elements app version and build (not the component) |
| [`rw.page`](/elements/api-reference/components/hooks.js/available-data/rw.page.md)                           | Current page data (id, title, filename, etc.)      |
| [`rw.node`](/elements/api-reference/components/hooks.js/available-data/rw.node.md)                           | Component node data (id, title, parent, etc.)      |
| [`rw.component`](/elements/api-reference/components/hooks.js/available-data/rw.element.md)                   | Component metadata (title, assetPath, etc.)        |
| [`rw.theme`](/elements/api-reference/components/hooks.js/available-data/rw.theme.md)                         | Theme data including breakpoints                   |
| [`rw.pages`](/elements/api-reference/components/hooks.js/available-data/rw.pages.md)                         | Site navigation page tree                          |

### Available Functions

| Function                                                                                                      | Description                            |
| ------------------------------------------------------------------------------------------------------------- | -------------------------------------- |
| [`rw.setProps()`](/elements/api-reference/components/hooks.js/available-functions/rw.setprops.md)             | Pass data to templates                 |
| [`rw.setRootElement()`](/elements/api-reference/components/hooks.js/available-functions/rw.setrootelement.md) | Configure the root HTML element        |
| [`rw.addAnchor()`](/elements/api-reference/components/hooks.js/available-functions/rw.addanchor.md)           | Register an anchor for the link picker |
| [`rw.resizeResource()`](/elements/api-reference/components/hooks.js/available-functions/rw.resizeresource.md) | Resize image resources                 |
| [`rw.getBreakpoints()`](/elements/api-reference/components/hooks.js/available-functions/rw.getbreakpoints.md) | Get theme breakpoint data              |

## Basic Example

Here's a complete example showing how hooks transform properties before they reach the template:

**properties.json**

```json
{
    "title": "Padding",
    "property": "padding",
    "default": 5,
    "slider": {
        "min": 0,
        "max": 12,
        "round": true
    }
}
```

**hooks.js**

```javascript
const transformHook = (rw) => {
    const { padding } = rw.props;
    
    // Double the padding value
    rw.setProps({
        padding: padding * 2
    });
};

exports.transformHook = transformHook;
```

**template.html**

```html
<div style="padding: {{padding}}px">
    Content with transformed padding
</div>
```

When the slider is set to 5, the template receives 10 (5 × 2).

## Conditional Class Generation

A common use case is generating CSS classes based on multiple properties:

```javascript
const transformHook = (rw) => {
    const {
        customSizing,
        size,
        fontSize,
        paddingTop,
        paddingRight,
        paddingBottom,
        paddingLeft
    } = rw.props;
    
    const sizeClasses = [
        !customSizing && size,
        customSizing && fontSize,
        customSizing && paddingTop,
        customSizing && paddingRight,
        customSizing && paddingBottom,
        customSizing && paddingLeft,
    ]
        .filter(Boolean)
        .join(" ");

    rw.setProps({
        classes: sizeClasses
    });
};

exports.transformHook = transformHook;
```

```html
<div class="{{classes}}">Content</div>
```

## Edit vs Preview Mode

You can detect whether the component is being viewed in the editor or preview:

```javascript
const transformHook = (rw) => {
    const { mode } = rw.project;
    
    rw.setProps({
        isEditMode: mode === 'edit',
        isPreviewMode: mode === 'preview'
    });
};

exports.transformHook = transformHook;
```

## Next Steps

* [Passing Data to Templates](/elements/api-reference/components/hooks.js/passing-data-to-templates.md) - Detailed examples of using `rw.setProps()`
* [Working with Collections](/elements/api-reference/components/hooks.js/working-with-collections.md) - Accessing and transforming collection data
* [Working with Resources](/elements/api-reference/components/hooks.js/working-with-resources.md) - Handling images and other resources
* [Common Use Cases](/elements/api-reference/components/hooks.js/common-use-cases.md) - Practical recipes and patterns
* [Building Complex Components](/elements/api-reference/guides.md) - Guides showing hooks at work in real components


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

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

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.realmacsoftware.com/elements/api-reference/components/hooks.js.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
