Persisting state
Remember states across page loads.
How it works
Both components determine the initial state on every page load from these sources, checked in order:
- URL param (
?panel=): Reading of the URL parameter will always be done, no config needed. See Deep linking. - localStorage: used when
persistis enabled and no URL param applied. See below. - HTML default: the markup state like
class="active"panel (PanelSet) orclass="is-open"(Panel / closable PanelSet).
localStorage is only read when you opt in via persist. A component without it always uses the URL param or its HTML default, so a stored entry from another page can never reopen it unexpectedly.
On this page we delve a bit deeper into persisting state.
Reading localStorage
Reading is opt-in. localStorage is only checked on load when the component has persist enabled. Without it, the stored value is ignored and the HTML default is used.
State is stored under keys scoped to the current page path, so auto-assigned ids (panel-1, panel-2, …) on different pages never collide:
| Component | Key format | Example (on /docs/tabs) |
|---|---|---|
| PanelSet | <pathname>::ps:<container-id> |
/docs/tabs::ps:main-tabs |
| Panel | <pathname>::panel:<element-id> |
/docs/tabs::panel:sidebar |
The <pathname> prefix is location.pathname, added automatically. You don’t set it. It just keeps each page’s state separate.
Writing localStorage
Writing is optional. Enable persist to save panel state to localStorage whenever a panel opens or closes. On the next load, the stored state is restored automatically.
Persist in Panel
Key Features
- This is our most important feature ever!
new Panel('#sidebar', { persist: true });
// or via init
Panel.init({ persist: true });
<div id="sidebar" data-panel data-panel-persist>...</div>
Persist in PanelSet
Key Features
- This is our most important feature ever!
Pricing Plans
- Starter Plan: Whenever you don’t want to pay a lot.
- Professional Plan: Ideal for managers who like to spend money!
Support Options
- If you send us an email, we will probably ignore it.
- We don’t even have a community forum.
- Opening an issue on GitHub is your next best option. Or even better: PR’s! You do the work!
new PanelSet('#tabs', { persist: true });
// or via init
PanelSet.init({ persist: true });
<div id="tabs" data-panelset data-panel-persist>...</div>
Note: a PanelSet uses data-panel-persist (the panel- prefix), not data-panelset-persist. The persistence attributes are shared with Panel, so the prefix stays panel- on both.
Play around with the two examples above, and reload the page. Both come back in the same state you left them.
For accordion groups, set data-panel-persist on the [data-panel-group] element to cover all panels in the group at once.
Global persist and opting out
init({ persist: true }) turns persistence on for every matching component. Two things keep that from being heavy-handed:
- An
idis required to store anything. A PanelSet writes under its containerid; a Panel under its elementid. A component without anidsilently persists nothing, so a global flag only saves the components you’ve deliberately identified. - Any component can opt out. A per-element
data-panel-persist="false"overrides the global option (attributes are the most specific setting). Inside a persisting[data-panel-group], a panel’s owndata-panel-persist="false"also wins over the group.
<!-- Persists: inherits init({ persist: true }) and has an id-->
<div id="saved" data-panelset>
<div class="panel-wrapper">...</div>
</div>
<!-- Never persists: no id to key on-->
<div data-panelset>
<div class="panel-wrapper">...</div>
</div>
<!-- Opts out explicitly, even under a global persist-->
<div id="opted-out" data-panelset data-panel-persist="false">
<div class="panel-wrapper">...</div>
</div>