Skip to content

Partial Navigation

modules/partial-navigation.js turns links inside a section into in-place updates: the next page is fetched, and only that section is replaced. The rest of the page, scroll position and any playing media stay as they are.

It suits paginated or filtered lists, such as a news overview.

Give the section an id and the data-partial-navigation attribute, and point its links at that id:

<section id="news" data-partial-navigation>
{% include 'partials/filters.twig' %}
{% for post in posts %}
{% include 'partials/teasers/post.twig' %}
{% endfor %}
<a href="{{ posts.pagination.next.link }}#news">Next</a>
</section>

The module is loaded automatically when the attribute is on the page.

A click on a link inside the section whose URL ends in #<section id>:

  1. fetches the URL and takes the element with the same id from the response
  2. replaces the section’s content with it and pushes the URL to the history
  3. scrolls the section into view when its top is above the viewport

Links to another #hash, another site, opened with a modifier key or with target="_blank" are left alone. Back and forward restore the section through the same fetch.

When a request fails or the response has no element with the section’s id, the browser navigates to the URL normally.

While a request takes longer than 150 ms the section gets aria-busy="true", which base/_partial-navigation.scss dims. scroll-margin-top uses --instance-site-header-height, so the section isn’t scrolled under a sticky header.

  • The section id is the same on every page the links lead to.
  • The server renders the full page for these URLs; nothing else needs to change on the PHP side.