---
name: "up.Preview.prototype.undo"
area: "API"
kind: "Instance method"
parent: "up.Preview class"
url: "https://unpoly.com/api/up.Preview.prototype.undo"
---
<nav aria-label="Unpoly docs">[All docs](https://unpoly.com/index.md) · [up.Preview class](https://unpoly.com/api/up.Preview.md)</nav>

# up.Preview.prototype.undo(undoFn)

Register a function that will revert this preview's effects when the preview [ends](https://unpoly.com/learn/previews.md#ending).

See [Advanced preview mutations](https://unpoly.com/learn/previews.md#advanced-mutations) for an elaborate example.

## Example {#example}

The preview below sets a `[foo]` attribute on the targeted fragment. It uses `#undo()` to remove the attribute when the preview ends:

```js
up.preview('my-preview', function(preview) {
  if (preview.fragment.hasAttribute('foo')) return
  preview.fragment.setAttribute('foo', 'foo-value')
  preview.undo(() => preview.fragment.removeAttribute('foo'))
})
```

Instead of registering a callback with `#undo()` a preview function can also return a function:

```js
up.preview('my-preview', function(preview) {
  if (preview.fragment.hasAttribute('foo')) return
  preview.fragment.setAttribute('foo', 'foo-value')
  return () => preview.fragment.removeAttribute('foo')
})
```

Common DOM mutations can be expressed more concisely using an [`up.Preview`](https://unpoly.com/api/up.Preview.md) method. These methods automatically undo their changes, without you needing to call `#undo()`:

```js
up.preview('my-preview', function(preview) {
  preview.setAttrs({ foo: 'foo-value' })
})
```

---

## Parameters {#parameters}

### undoFn {#undoFn}

(required)

A function that will be called when the preview ends.

Type: Function

