# Loading states & dynamic metadata The router provides flexible loading control with support for three distinct patterns, allowing you to choose the approach that best fits your application architecture. ## Pattern 1: Router-managed loading (zone-specific) Use `loadingComponent` with `shouldDisplayLoadingOnRouteLoad: true` for multi-zone layouts where the Router manages the loading state: > **⚠️ You must call `hideLoading()` from the route component.** When > `shouldDisplayLoadingOnRouteLoad: true` is set, the router mounts the route > component immediately but keeps it hidden under `loadingComponent` and waits > for an explicit `hideLoading()` signal before revealing it. If the component > never calls `hideLoading()` (forgotten, thrown before reaching it, conditional > code path that didn't run), the loading screen stays up forever and the real > component never appears — the route is effectively bricked until the user > navigates away. In development, a `console.warn` fires after 10 seconds to > surface this; production has no automatic recovery. ```javascript import { createRoute } from '@keenmate/svelte-spa-router/wrap' import { hideLoading } from '@keenmate/svelte-spa-router/helpers/route-metadata' import Loading from './components/Loading.svelte' const routes = { '/document/:id': createRoute({ component: () => import('./routes/DocumentDetail.svelte'), loadingComponent: Loading, shouldDisplayLoadingOnRouteLoad: true, // Keep loading visible until component signals ready title: 'Document Detail', breadcrumbs: [ { label: 'Home', path: '/' }, { label: 'Documents', path: '/metadata-demo' }, { id: 'documentDetail', label: 'Loading...', path: '/document/:id' } ] }) } ``` In your component, signal when data is loaded: ```svelte

{document?.name || 'Loading...'}

``` **Perfect for:** - Multi-zone layouts (toolpanel + content areas) - Apps where each zone needs its own loading UI - When you want the Router to manage loading component visibility ## Pattern 2: Component-managed loading (default) Components handle their own loading state with no special configuration: ```javascript const routes = { '/product/:id': createRoute({ component: () => import('./routes/ProductDetail.svelte'), title: 'Product Detail' }) } ``` ```svelte {#if loading}
Loading product...
{:else}

{product.name}

{product.description}

{/if} ``` **Perfect for:** - Simple apps with straightforward loading needs - Components that manage their own UI states - When you want full control over loading presentation ## Pattern 3: Global loading overlay (user-defined) Define a global loading overlay in your `App.svelte` that reacts to route loading state: ```svelte
{#if isLoading}

Loading...

{/if}
``` Then manually control loading in your components: ```svelte ``` **Perfect for:** - Consistent loading UI across entire app - Apps with complex async operations beyond route loading - When you want a single global loading indicator ## Combining patterns You can combine Pattern 1 and Pattern 3 for comprehensive loading feedback: ```javascript // Route uses both loadingComponent and triggers global overlay '/document/:id': createRoute({ component: () => import('./routes/DocumentDetail.svelte'), loadingComponent: Loading, // Zone-specific loading shouldDisplayLoadingOnRouteLoad: true, // Also triggers global overlay title: 'Document Detail' }) ``` This shows both: - The `Loading` component in the content area (zone-specific) - The global overlay (if defined in App.svelte) ## Dynamic metadata helpers Update page metadata after data loads: ```javascript import { updateTitle, // Update just the title updateBreadcrumb, // Update specific breadcrumb by ID updateRouteMetadata // Update full metadata object } from '@keenmate/svelte-spa-router/helpers/route-metadata' // Update title only updateTitle('Invoice.pdf') // Update specific breadcrumb by ID (partial update) updateBreadcrumb('documentDetail', { label: 'Invoice.pdf', path: '/document/123' }) // Update full metadata updateRouteMetadata({ title: 'Invoice.pdf', breadcrumbs: [ { label: 'Home', path: '/' }, { label: 'Documents', path: '/documents' }, { label: 'Invoice.pdf', path: '/document/123' } ] }) ``` ## Reactive metadata access Access current route metadata reactively: ```svelte

{title || 'Default Title'}

{#if breadcrumbs.length > 0} {/if} ``` **Available helpers:** ```javascript import { // Loading state control showLoading, // Manually show loading state hideLoading, // Hide loading state (signal component is ready) routeIsLoading, // Check if currently loading (reactive) // Metadata updates updateTitle, // Update just the title updateBreadcrumb, // Update specific breadcrumb by ID updateRouteMetadata, // Update full metadata object // Reactive metadata access routeTitle, // Get current title routeBreadcrumbs, // Get current breadcrumbs routeContext // Get full route context object } from '@keenmate/svelte-spa-router/helpers/route-metadata' ``` See `/loading-demo` and `/document/:id` routes in the example-history app for complete interactive demos.