composability

Build reusable route configuration factories with globally importable helpers in @rangojs/router.

Updated Nov 7, 2025
One-click install
npx skills add https://github.com/rangojs/rango --skill composability-rangojs
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: composability
Source: https://github.com/rangojs/rango/tree/main/packages/rangojs-router/skills/composability
Command: npx skills add https://github.com/rangojs/rango --skill composability-rangojs

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill requires @rangojs/router.

What problem does it solve? Sharing loaders, middleware, caching, and error handling across many route files in a Rango application leads to copy-pasted configuration that drifts out of sync. This Skill documents how to extract repeated route setup into typed, composable factories using globally importable helpers from @rangojs/router. ## Core Features & Use Cases - Globally Importable Helpers: Import cache, middleware, revalidate, loader, loading, parallel, intercept, errorBoundary, and notFoundBoundary directly from @rangojs/router and call them inside factories, while path() and include() stay in the urls() callback to keep route structure visible. - Composition Factories: Define intention-named factories like withAuth() or withCaching() that return arrays of use items, flattened automatically up to 3 levels inside path() or layout() use callbacks. - Async Code-Splitting with include(): Split route groups behind () => import() thunks with measured first-hit latency guidance, naming behavior (shop.index namespacing vs flattening), and full type generation retained. - Typed Factories: Use RouteUseItem[], LayoutUseItem[], and UseItems<T> to type factory return values. - Use Case: An app with blog, shop, and admin sections shares auth middleware, cache TTLs, and loading skeletons through factories defined in a central route-config.ts module instead of repeating them per route. ## Quick Start Show me how to create a reusable withAuth and withCaching factory and apply them to my Rango route definitions.

Frequently Asked Questions about composability

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I share middleware and loaders across routes in Rango?

Import helpers like cache, middleware, revalidate, and loading directly from @rangojs/router and wrap them in factory functions such as withAuth() or withCaching(). Call those factories inside path() or layout() use callbacks; returned arrays are flattened automatically up to 3 levels.

Why can't path() and include() be used in route factories?

path() and include() define the route structure itself, so they stay exclusive to the urls() callback to keep the URL tree readable at a glance. Only configuration helpers like cache, middleware, and loading are globally importable because they modify behavior without defining routes.

Does async include() in Rango affect route types and reverse()?

No. Build-time discovery awaits the import thunk, so href(), reverse(), generated route types, and prerendering still see every route in a code-split group. Only the module's runtime evaluation is deferred until the first matching request.

When should I use async include() versus eager include()?

Prefer the async form for large, independently loadable groups like admin areas or localized sections, since first-hit cost scales with routes per chunk. Keep the eager form for small groups or ones sharing most of their module graph with the entry bundle.

Why does my shared revalidate factory override route defaults?

A hard false from ?? false in a shared predicate ends the revalidation chain and overrides each route's own default. Use || undefined to defer instead, and match actions with ctx.isAction(Action) so renames surface as compile errors.