---
name: "up.macro"
area: "API"
kind: "JavaScript function"
parent: "up.script module"
url: "https://unpoly.com/api/up.macro"
---
<nav aria-label="Unpoly docs">[All docs](https://unpoly.com/index.md) · [up.script module](https://unpoly.com/api/up.script.md)</nav>

# up.macro(selector, [options], macro)

Registers a [compiler](https://unpoly.com/learn/enhancing-elements.md) that is run before all other compilers.

A macro lets you set attributes that will be compiled afterward.

If you want default attributes for _every_ link and form, consider customizing your [navigation options](https://unpoly.com/learn/navigation-defaults.md) or configuring Unpoly to [handle everything](https://unpoly.com/learn/handling-all-links.md).

<nav aria-label="Guides">

- [Learn: Enhancing elements with JavaScript](https://unpoly.com/learn/enhancing-elements.md#macros)

</nav>

## Example {#example}

In this example every link opens a modal with a [custom animation](https://unpoly.com/api/up.animation.md) `shake`:

```html
<a href="/page1" up-layer="new modal" up-class="warning" up-animation="shake">Page 1</a>
<a href="/page2" up-layer="new modal" up-class="warning" up-animation="shake">Page 2</a>
<a href="/page3" up-layer="new modal" up-class="warning" up-animation="shake">Page 3</a>
```

A new `[shake-modal]` attribute would make the same links shorter:

```html
<a href="/page1" shake-modal>Page 1</a>
<a href="/page2" shake-modal>Page 2</a>
<a href="/page3" shake-modal>Page 3</a>
```

We can define the `[shake-modal]` attribute by registering a macro that sets the `[up-layer]`, `[up-class]`, and `[up-animation]` attributes for us:

```js
up.macro('[shake-modal]', function(link) {
  link.setAttribute('up-layer', 'new modal')
  link.setAttribute('up-class', 'warning')
  link.setAttribute('up-animation', 'shake')
})
```

---

## Parameters {#parameters}

### selector {#selector}

(required)

The selector to match.

Type: string

### [options.priority=0] {#options.priority}

(optional)

The priority of this compiler.

Compilers with a higher priority are run first. Two compilers with the same priority are run in the order they were registered.

Type: number

### [options.batch=false] {#options.batch}

(optional)

If set to `true` and a fragment insertion contains multiple elements matching `selector`, the `compiler` function is only called once with all these elements.

Type: boolean

### macro {#macro}

(required)

The function to call when an element matching `selector` is inserted.

Up to three arguments can be accepted:

1. The newly inserted `element` matching the selector
2. Any [data attached to the element](https://unpoly.com/learn/data.md)
3. [Meta information](https://unpoly.com/learn/enhancing-elements.md#meta) about the current render pass

The function may return a [destructor function](https://unpoly.com/learn/enhancing-elements.md#destructor) that is called before it is removed from the DOM. The destructor function is called with the compiled element.

The compiler function can be [`async`](https://unpoly.com/api/up.compiler.md#async).

Type: Function(element, [data](https://unpoly.com/learn/data.md), meta): (Function|[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)<Function>|[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises)<Function>|undefined)

