Data with load()
load is a plain object literal, not a function — Nexa Core never executes developer JavaScript, it only analyzes it. Declare a URL, and the result becomes available as data inside the page.
Declaring load
export const load = { url: "/products/:slug" };:slug is substituted with the route's real parameter before requesting the URL against NEXA_API_URL.
Using the data
export default function ProductPage() {
return (
<article>
<h1>{data.name}</h1>
<p>{data.price}</p>
</article>
);
}data.* is available in the JSX body, in seo, and in schema — resolved at build time or on the fly, depending on the command.
Pre-rendering dynamic routes
export const paths = { url: "/products" };
// nexa build requests /products, expects [{"slug":"iphone-17"}, ...]
// and generates a real dist/products/iphone-17/index.htmlIf the page also declares paths (same shape as load), nexa build requests that list and generates a real index.html for each combination — genuinely static HTML, with no Nexa server running in production.
Iterating lists with <For>
export const load = { url: "/products" };
export default function Catalog() {
return (
<ul>
<For each={data.items}>
{(item) => (
<li><a href={`/products/${item.slug}`}>{item.name}</a></li>
)}
</For>
</ul>
);
}A catalog, an article listing, a directory — <For> is one more syntactic pattern, recognized just like t() or onClick, never an arbitrary .map(): each only accepts data.x/params.x, and the callback returns a single JSX element per item. Before this, the only way to show a list was inside an island, losing the real HTML that is Nexa's whole reason to exist — with <For>, every <li> is indexable content from the very first byte.