Heimdall Docs

Swaps

A swap controls how Heimdall applies returned HTML to the DOM. This is one of the core concepts of the framework.

Choosing the right swap determines whether you replace content, replace the host element, append to a list, prepend new items, or do no direct DOM update at all.

1. What a Swap Is

When an action returns HTML, Heimdall needs to know where and how that HTML should be applied. The target chooses where. The swap chooses how.

button.Heimdall()
    .Click("Example.Refresh")
    .Target("#result")
    .SwapInner();

2. The Available Swap Modes

Heimdall supports a small set of explicit swap modes. These map directly to the client runtime.

inner — replace the contents of the target element
outer — replace the target element itself
beforeend — append returned HTML inside the target
afterbegin — prepend returned HTML inside the target
none — do not apply the main response directly to the target

3. Inner Swap

Use inner when you want to keep the host element stable and replace only its contents. This is a very common choice for forms, panels, and content regions.

button.Heimdall()
    .Click("Example.Refresh")
    .Target("#result")
    .SwapInner();

4. Outer Swap

Use outer when the returned HTML should replace the target element itself. This is useful when the server returns a fully refreshed host with new state or attributes.

button.Heimdall()
    .Click("Counter.Increment")
    .Target("#counter-host")
    .SwapOuter();

5. Append with BeforeEnd

Use beforeend when you want to append new content to the end of a target. This works well for lists, feeds, and toast containers.

button.Heimdall()
    .Click("Notes.Add")
    .Target("#notes-list")
    .SwapBeforeEnd();

6. Prepend with AfterBegin

Use afterbegin when new content should appear at the beginning of the target. This is useful for newest-first lists, notifications, and toasts.

button.Heimdall()
    .Click("Toast.Create")
    .Target("#toast-manager")
    .SwapAfterBegin();

7. No Direct Swap

Use none when the main response should not be directly inserted into the target. This is especially useful when the response is only performing out-of-band updates.

button.Heimdall()
    .Click("Toast.Publish")
    .SwapNone();

8. Strongly Typed Markup and Rendered HTML

Heimdall helpers emit plain HTML attributes. The swap mode is part of the browser-side contract.

Strongly Typed Markup

button.Heimdall()
    .Click("Example.Refresh")
    .Target("#result")
    .SwapInner();

Rendered HTML

<button
  heimdall-click="Example.Refresh"
  heimdall-target="#result"
  heimdall-swap="inner">
</button>

9. Choosing the Right Swap

A good rule of thumb is to choose the smallest swap that preserves the structure you want to keep.

Use Inner When

  • The target element should stay in place
  • Only the contents need to change
  • You want a stable host for future targeting

Use Outer When

  • The host element itself has changed
  • New state or attributes belong on the host
  • The server returns a complete replacement boundary

Use BeforeEnd / AfterBegin When

  • You are growing a list or collection
  • You want to append or prepend items
  • The existing list should remain intact

Use None When

  • The response only performs out-of-band updates
  • You do not want a direct main-target update
  • The action triggers other UI changes instead

10. Common Pattern: Stable Host

A very common Heimdall pattern is to keep a host element stable with an inner swap. This makes targeting reliable and keeps the DOM boundary consistent.

<div id="form-host">
  <!-- server-rendered form -->
</div>

11. Common Pattern: Replace the Host

When the host itself carries important state or attributes, an outer swap is often the better choice.

<div id="counter-host" data-heimdall-state='{"count":1}'>
  ...
</div>

Next Steps

Once swaps make sense, the next concept is state. That is where Heimdall starts to feel especially different.