Revision code

Changes Version 2.3.0
Released on August 31, 2021 with 50 commits

More control over loading Unpoly

  • Unpoly can now be loaded with <script defer>. This can be used to load your scripts without blocking the DOM parser.
  • Unpoly can now be loaded with <script type="module">. This can be used deliver a modern JS build to modern browsers only.
  • Unpoly can now be booted manually at a time of your choice. By default Unpoly boots automatically once the initial DOM is parsed.
  • Event listeners registered with up.on() will no longer be called before Unpoly was booted. Like with compilers, this lets you register behavior that is only active on supported browsers.
  • Unpoly no longer boots on Edge 18 or lower. Edge 18 was the last version of Edge to use Microsoft's custom rendering engine. Later versions use Chromium.

Compatibility with strict Content Security Policies (CSP)

When your Content Security Policy disallows eval(), Unpoly cannot directly run JavaScript code in HTML attributes. This affects [up-on-...] attributes like [up-on-loaded] or [up-on-accepted].

Unpoly 2.3 lets your work around this by prefixing your callback with a CSP nonce:

<a href="/path" up-follow up-on-loaded="nonce-kO52Iphm8B alert()">Click me</a>

Users of the unpoly-rails gem can insert the nonce using the up.safe_callback helper:

<a href="/path" up-follow up-on-loaded="<%= up.safe_callback('alert()') %>">Click me</a>

Also see our new guide to working with strict Content Security Policies.

New options for existing features

Request-related events now expose additional context about the event. This affects the events up:fragment:loaded, up:request:load, up:request:loaded, up:request:aborted, up:request:fatal.

The link or form element that caused the request can now be access through event.origin.

The layer associated with the request can now be accessed through event.layer. If the request is intended to update an existing fragment, this is that fragment's layer. If the request is intended to open an overlay, the associated layer is the future overlay's parent layer.

Various changes

  • Fix a bug with a[up-back] where Unpoly would follow the link's default [href] instead of visiting the previous URL.
  • Fix a bug where the URL pattern * would not match most URLs when the current location is multiple directories deep.
  • When a target cannot be found and a fallback target is used, Unpoly now logs a message.
  • When a compiler is registered after booting, Unpoly now explains in the log that the compiler will only run for fragments inserted in the future.
  • up.observe() and input[up-observe] now log a warning when trying to observe a field without a [name] attribute.
  • up.browser.loadPage() has been renamed to
  • up.browser.isSupported() has been renamed to up.framework.isSupported().


If you're upgrading from an older Unpoly version you should load unpoly-migrate.js to polyfill deprecated APIs. Changes handled by unpoly-migrate.js are not considered breaking changes.

See our upgrading guide for details.