Getting started with Unpoly

Unpoly is an unobtrusive Javascript framework for applications that render on the server. It allows your views to do things that are not normally possible in HTML, such as having links update only fragments of a page, or opening links in modal dialogs.

Unpoly can give your server-side application fast and flexible frontends that feel like a single-page application (SPA). It also preserves the resilience and simplicity of the server-side programming model.

Installation

You can install Unpoly by either downloading the library files or using package managers like npm or RubyGems.

If you just want to test-drive Unpoly, the easiest way is to link to a CDN.

Thinking with fragments

In a traditional web application, the entire page is destroyed and re-created when the user follows a link:

This makes for an unfriendly experience: Whenever a link is followed, the scroll position is reset, the page flashes, DOM changes caused by Javascript get lost, unsaved form fields are discarded.

With Unpoly the server still renders full HTML pages, but we only use fragments and discard the rest:

With this model, following links feels smooth. All transient DOM changes outside the updated fragment are preserved. Pages also load much faster since the DOM, CSS and Javascript environments do not need to be destroyed and recreated for every request.

All fragment updates change the browser URL by default. The back button works as expected.

Example

Give a link an up-target attribute to update a CSS selector with the same selector from the link's destination. No server-side changes required.

back.html
<a href="front.html" class="one" up-target=".one">
  Flip
</a>

<a href="front.html" class="two" up-target=".two">
  Flip
</a>
front.html
<a href="back.html" class="one" up-target=".one">
  &hearts;
</a>

<a href="back.html" class="two" up-target=".two">
  &spades;
</a>

You can learn more in Linking to fragments, or continue with the tutorial below.

Leveraging layers

Layered interactions, like modal dialogs, can make a frontend easier to both use and implement. Using layers we can keep an unfinished interaction open in the background, branch out to an interaction in an overlay, and return to the background page when we're done.

Below you see a screenshot of a layered interaction in Gmail. The mail editor has been stacked on top of the message list as a modal dialog. Inside the dialog we see a third layer, the autocomplete results, as a pop-up overlay:

An interaction like the Gmail example is pretty straightforward to build with Unpoly. Unpoly lets you stack an arbitrary number of overlays on top of each other. Each layer has its own URL:

The content inside a modal is rendered as a full HTML page, but we only use a fragment for the modal content and discard the rest. This allows you to render any response either as a full page or inside a modal or pop-up.

Using fragment links it's also simple to stay inside a modal or pop-up during an interaction that spans multiple pages. Links prefer to update fragments within the same layer, while preserving the content of lower layers. You can even submit forms without leaving the modal or pop-up.

Example

Give a link an [up-layer=new] attribute to extract a CSS selector from the destination and open the fragment in a modal dialog. No server-side changes required.

preview.html
<main>

  <p>Story summary</p>

  <a href="full.html" up-layer="new">
    Read full story
  </a>

</main>
full.html
<main>

  <h2>Full story</h2>

  <p>Lorem ipsum dolor sit amet.</p>

</main>

Learn more about overlays or continue with the tutorial below.

Animation

Have you noticed how pages fade in and out as you follow links on this site, unpoly.com?

Whenever you update a page fragment you can animate the change. Unpoly comes with a number of predefined transitions, like a cross-fade or sweeping motion and you can define your own with a few lines of Javascript.

Example

Give a fragment link an up-transition attribute to animate between the old and new fragment.

story1.html
<main>

  <h1>The first story</h1>

  <a href="story2.html" up-transition="move-left" up-follow>
    Show next story
  </a>

</main>
story2.html
<main>

  <h1>The second story</h1>

  <a href="story1.html" up-transition="move-right" up-follow>
    Show previous story
  </a>

</main>

Learn more about animation, or continue with the tutorial below.

Organizing Javascript snippets

Every app needs a way to activate JavaScript behavior on certain HTML elements. Here are some examples:

  • An <input type="search"> should request search results when the user types something
  • A <textarea class="wysiwyg"> should automatically activate a WYSIWYG editor like Redactor
  • A <div class="map"> should render a map with the Google Maps API

Unpoly lets you organize your JavaScript snippets with compiler functions. Your compilers will be called whenever a matching element enters the DOM, either when the page loads or when updating a fragment.

Example

page.html
<p>
  The time is <span class="timestamp"></span>
</p>
scripts.js
up.compiler('.timestamp', (element) => {
  var now = new Date()
  element.innerText = now
})

Extending Unpoly

Unpoly comes with an extensive Javascript API. Want to update a fragment from your own code? There's a function for that:

up.render('.story', { url: 'full.html' });

Similar functions exist for every unobtrusive Unpoly feature, be it opening an overlay, submitting a form with AJAX or morphing elements. The API docs list these function along their unobtrusive counterparts.

You can even invent your own magic HTML attributes using compilers.

Ready for more?

This tutorial covered just the most basic features of Unpoly.

We recommend checking out the demo application that shows some of Unpoly's more advanced capabilities.

The other guides explain all of Unpoly's features in great detail: