Learn Unpoly

Guides that explain how Unpoly works and how to use it.
Looking up a specific attribute or function? See the API reference.

Start here

Getting started

Unpoly lets your links and forms update fragments of the current page, instead of loading full new documents. Screens update without a full page load and keep their state. Your app stays on the server, rendering HTML with any language and any framework.

  1. Links

    Unpoly enhances links so they update a fragment of the current page, instead of loading a full new document. The rest of the page keeps its state: scroll positions, focus, unsaved form fields and running scripts all survive the click.

  2. Forms

    Unpoly submits forms and updates a fragment of the current page with the response. Your server keeps rendering plain HTML, and one convention on your backend also makes validation errors work. Fields can also re-render parts of the form while the user is still filling it in.

  3. Overlays

    Unpoly can open any URL in an overlay, like a modal dialog or a drawer. An overlay can show a single fragment or host an interaction that spans multiple pages. When it closes, an overlay can pass a result value back to the layer that opened it.

  4. Loading state

    While Unpoly waits for the server, it can show loading state, like a spinner, a skeleton screen or even the expected result. Every effect appears instantly after the user's interaction and is reverted when the request ends. This makes your app feel responsive, even when the server takes a moment to answer.

  5. Live fragments

    Live fragments are elements that update without being targeted by a link or form. They load lazily, poll, react to server events, or piggy-back on other responses. Your server renders their content like any other page.

  6. History

    Unpoly keeps the browser history working while it updates fragments. When a link or form changes the page's main fragment, the address bar and window title change as they would for a full page load, and the Back button brings the earlier page back.

  7. Scrolling & focus

    After a fragment update, Unpoly decides what scrolls and what gets focus. Following a link scrolls to the top and focuses the new content, the way a full page load would. A minor update leaves scroll positions and focus where they are. Every default can be changed per link, per form or globally.

  8. Network & caching

    All of Unpoly's requests go through one HTTP client. It caches responses so revisited pages render instantly, revalidates cached content so stale data is quickly replaced, aborts requests that would race each other, and handles disconnects without the browser's error screen. This works without setup, and every part can be changed for a single link, a form or your whole app.

  9. Motion

    Unpoly can animate a fragment update: the old content fades or slides out while the new content comes in. You pick a motion effect by name in an HTML attribute, or define your own with a few lines of JavaScript. Users who have asked their system to reduce motion get instant updates instead.

  10. Scripting

    Unpoly pairs HTML elements with JavaScript behavior. Instead of running scripts once per page load, you register compilers that enhance matching elements whenever they enter the page: at the initial load, and again with every fragment update.

  11. Backend integration

    Unpoly works with any backend that renders HTML. Requests from Unpoly look like regular browser requests, and the server answers with full pages, using the routes and templates it already has. Optional HTTP headers let the server shorten its responses, skip unchanged content, or steer the frontend.

  12. Advanced rendering

    Every link, form, overlay or poll that Unpoly handles ends in the same render pass, and every render pass takes the same options. This chapter covers those options: which fragments are updated, what else happens on a navigation, what to do when the server reports an error, and how your code can hook into the process.

  13. Extensions

    Unpoly works without extensions. This chapter collects the optional tooling around the core, for when it saves you work.