Condition Mobile example
How it works
A library that is only imported when a condition is true at load time. The condition lives in resources.js, next to the library, not in the handler.
Every library in Punky is an entry of getModules() in src/js/resources.js: a name and an async resource that imports it. An entry can also carry options.condition, an async function that returns a boolean. When a handler asks for its library, loadLibrary runs that function first. If it returns false, the import is skipped, no instance is created, and the debug log shows the library as skipped by condition. The handler, the class and the markup are all untouched: they just never run.
The condition is evaluated once, when the library is first requested on a page. It does not react to a resize and it is not checked again later. It is a loading decision, not a responsive one: a library that is only worth its bytes on phones, a behaviour that only makes sense on touch devices, a breakpoint read at load. A feature that must come and go as the window changes should be imported normally and handle its own init and destroy on resize.
Condition is the smallest possible example of that: a local class that writes a card into an empty div. Nothing in it knows about the viewport. The 810px limit is in its resources.js entry, and that is the only place to change it.
The markup
An empty div with the js--tablets-condition hook. There is nothing else to put in the HTML; the class fills it when the condition lets it be built.
<!-- An empty div with the hook. The class fills it, if it is ever built -->
<div class="js--tablets-condition"></div> The handler
Handler.js is a plain handler: one selector, one config that passes the element on, and the usual swup lifecycle. It has no idea the library is conditional.
this.config = ({element}) => ({
element,
}); The resources.js entry
This is where the condition lives. The entry is like any other, plus options.condition. The function is async so it can also wait for something, such as a media query or a capability check, before answering:
{
name: "Condition",
resource: async () => {
const { default: Condition } = await import("@js/handler/condition/Condition.js");
return Condition;
},
options: {
condition: async () => {
return window.innerWidth < 810; // tablet s
}
}
}, And the check that reads it, in loadLibrary:
// resources.js: loadLibrary runs the condition once, before the import. False means no import,
// no instance, nothing else to do
if (library?.options?.condition && typeof library?.options?.condition == "function") {
const shouldLoad = await library.options?.condition();
if (shouldLoad === false) {
return `⏩ Library ${libraryName} skipped by condition`;
}
} What the framework does for you
- Lazy loading. The handler asks for the library when the div gets within 30px of the viewport (Boostify scroll). The condition runs at that moment; if it passes, the class is imported once and cached by the Manager.
- Page transitions. Instances are destroyed before swup replaces the content, which empties the div, and rebuilt on the new page. The condition is asked again only if the library was never imported.
- Debug. Add
?debugto the URL: the import log says whether the library was loaded or skipped by its condition.
Mobile only
The card inside the box only exists below 810px. On a wider viewport the box stays empty.
condition: window.innerWidth < 810 The live example is the empty div from the markup above. On a phone or a small tablet the condition is true, the class is imported and the box gets a card. On a desktop the condition is false and the box stays empty: nothing was downloaded, nothing was built.
The card only loads when the viewport is under 810px. If you are reading this on a desktop, resize the window below that width and reload the page, or open it on a phone, to see it. Resizing alone is not enough: the condition is read once, at load.
// Condition.js: what the instance does once it exists
init() {
this.DOM.element.innerHTML = `
<div class="condition-card">
<p>Only loads when the viewport is under 810px (tablets)</p>
</div>
`;
} condition: window.innerWidth < 810 Options reference
One option, on the entry in resources.js.
| Option | Values | What it does |
|---|---|---|
options.condition | async function returning a boolean. No default: without it the library always loads | Run once by loadLibrary before the import. false skips the library on this page load: no import, no instance. Anything else loads it as usual |
The option belongs to the entry in getModules(), so any library can have one, not only Condition. The handler and the class do not need to know about it.