Edit this page

up.fragment up:fragment:loaded
DOM event

This event is emitted after the server response was loaded, but before the HTML is used to change a fragment.

This gives you a chance to inspect the response or DOM state right before a fragment would be inserted. You may then choose to change render options or abort the render pass to do something else instead.

The event is emitted on the targeted layer. When opening an overlay, the event is emitted on the parent layer of the new overlay.

This event is also emitted when using a cached response. This allows performing the same transformations to both cache hits and cache misses.

Render lifecycle

Example: Making a full page load instead

Event listeners may call event.preventDefault() on an up:fragment:loaded event to prevent any changes to the DOM and browser history.

This is useful to detect an entirely different page layout (like a maintenance page or fatal server error) which should be open with a full page load:

up.on('up:fragment:loaded', (event) => {
  let isMaintenancePage = event.response.header('X-Maintenance')

  if (isMaintenancePage) {
    // Prevent the fragment update and don't update browser history
    event.preventDefault() // mark-line

    // Make a full page load for the same request.
    event.request.loadPage() // mark-line
  }
})

Example: Changing render options

Instead of preventing the update, listeners may also access the event.renderOptions object to mutate options to the up.render() call that will process the server response:

up.on('up:fragment:loaded', async function(event) {
  // If we see an X-Course-Completed header, render the main target
  if (event.response.headers['X-Course-Completed']) {
    event.renderOptions.target = ':main' // mark-line
  }
})

Example: Do something else, then retry

You may retry a prevented fragment update later, by calling up.render(event.renderOptions):

up.on('up:fragment:loaded', async function(event) {
  // When we couldn't access a page since we're signed out, the server sends a header
  if (event.response.header('X-Session-Missing')) {
    // Don't render the error message
    event.preventDefault() // mark-line

    // Sign in using a modal overlay
    await up.layer.ask('/sign_in', { acceptEvent: 'app:session:created' })

    // Now that we're signed in, retry the original request
    up.render(event.renderOptions) // mark-line
  }
})

Example: Discarding a revalidation response

When rendering cached content that is too old, Unpoly automatically reloads the fragment to ensure that the user never sees expired content. This process is called cache revalidation.

To prevent the insertion of revalidated content after the server responded you may prevent the up:fragment:loaded event with an { revalidating: true } property.

The following would skip rendering a validation response if it has the same X-Version header as the original, stale response:

up.on('up:fragment:loaded', function(event) {
  if (event.revalidating) {
    let newVersion = event.response.header('X-Version')
    let oldVersion = event.expiredResponse.header('X-Version')
    if (newVersion === oldVersion) {
      event.skip()
    }
  }
})

Also see skipping unnecessary rendering.


Event properties

event.preventDefault()
required

Aborts this render pass without changes.

Programmatic callers will reject with an up.AbortError.

event.skip()
required

Finishes this render pass without changes, usually to not re-insert identical content.

Programmatic callers will fulfill with an empty up.RenderResult.

To configure global rules for responses that should be skipped, you may also use up.fragment.config.skipResponse instead of registering an up:fragment:loaded listener.

event.request
required

The original request to the server.

event.response
required

The response received from the server.

event.revalidating
required

Whether responding to a cache revalidation request.

boolean
event.expiredResponse
required

When revalidating, this property is set to the expired content that is being reloaded to ensure that the user never sees stale content.

You may compare the { response } and { expiredResponse } properties to prevent re-insertion of identical content.

Also see up.fragment.config.skipResponse.

event.origin
required

The link, input or form element that caused the fragment update.

If no origin element is known, this property is left undefined.

event.renderOptions
required

Options for the up.render() call that will process the server response.

Listeners may inspect or modify these options.