# navigation_swap URL: /chirp/api/templating/navigation_swap/ Section: templating -------------------------------------------------------------------------------- navigation_swap - Chirp window.BENGAL_THEME_DEFAULTS = { appearance: 'light', palette: 'charcoal-bengal' }; window.Bengal = window.Bengal || {}; window.Bengal.enhanceBaseUrl = '/chirp/assets/js/enhancements'; window.Bengal.watchDom = true; window.Bengal.debug = false; window.Bengal.enhanceUrls = { 'toc': '/chirp/assets/js/enhancements/toc.736b857e.js', 'docs-nav': '/chirp/assets/js/enhancements/docs-nav.57e4b129.js', 'tabs': '/chirp/assets/js/enhancements/tabs.aac9e817.js', 'lightbox': '/chirp/assets/js/enhancements/lightbox.1ca22aa1.js', 'interactive': '/chirp/assets/js/enhancements/interactive.96c8880c.js', 'mobile-nav': '/chirp/assets/js/enhancements/mobile-nav.d991657f.js', 'action-bar': '/chirp/assets/js/enhancements/action-bar.d62417f4.js', 'copy-link': '/chirp/assets/js/enhancements/copy-link.7d9a5c29.js', 'data-table': '/chirp/assets/js/enhancements/data-table.1f5bc1eb.js', 'lazy-loaders': '/chirp/assets/js/enhancements/lazy-loaders.a5c38245.js', 'holo': '/chirp/assets/js/enhancements/holo.ee13c841.js', 'link-previews': '/chirp/assets/js/enhancements/link-previews.96620bcf.js' }; (function () { try { var defaults = window.BENGAL_THEME_DEFAULTS || { appearance: 'system', palette: '' }; var defaultAppearance = defaults.appearance; if (defaultAppearance === 'system') { defaultAppearance = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light'; } var storedTheme = localStorage.getItem('bengal-theme'); var storedPalette = localStorage.getItem('bengal-palette'); var theme = storedTheme ? (storedTheme === 'system' ? defaultAppearance : storedTheme) : defaultAppearance; var palette = storedPalette ?? defaults.palette; document.documentElement.setAttribute('data-theme', theme); if (palette) { document.documentElement.setAttribute('data-palette', palette); } } catch (e) { document.documentElement.setAttribute('data-theme', 'light'); } })(); Skip to main content For a complete page index, fetch /chirp/llms.txt. ⌁⌁ DocumentationInfoAboutGet StartedBuild AppsQuality and OperationsFile TextReferenceCubeExamplesApplied TutorialsReleasesDevGitHubChirp API ReferenceForum Magnifying Glass Search ⌘K Palette Appearance Chevron Down Mode Monitor System Sun Light Moon Dark Palette Snow Lynx Brown Bengal Silver Bengal Charcoal Bengal Blue Bengal List Chirp API Reference Caret Right Internal asgi invoke invoke_plan kwargs_resolve multimap types Caret Right Ai _providers _structured errors llm streaming Caret Right App compiler diagnostics lifecycle mount registry runtime server state url_for Caret Right Cache Caret Right Backends memory null redis deferred key middleware protocol Caret Right Cli Caret Right Templates minimal scaffold shell sse v2 _check _freeze _makemigrations _new _resolve _routes _run _security_check _templates Caret Right Contracts checker declarations patterns routes rules_accessibility rules_alpine_cdn rules_boundary rules_chirpui_runtime rules_commands rules_composition rules_context_cascade rules_csrf_forms rules_debug_wiring rules_defer_falsy rules_form_routes rules_forms rules_fragment_scope rules_fragment_targets rules_htmx rules_inline rules_islands rules_kida_analysis rules_layout rules_live_blocks rules_mount_app rules_oob_registry rules_oob_targets rules_page_handlers rules_page_shell rules_reactive rules_route_contract rules_route_names rules_safety rules_sse rules_swap rules_unreachable_blocks rules_vary template_scan types utils Caret Right Data Caret Right Drivers postgres sqlite Caret Right Schema diff generate introspect operations parse types _mapping _sqlite database errors migrate pagination query types Caret Right Docs autodoc checks collection frontmatter models plugin search tools Caret Right Ext chirp_ui Caret Right Http cookies forms headers query request response sync_request Caret Right I18N catalog detection formatting middleware Caret Right Markdown errors filters renderer Caret Right Middleware _redis_rate_limit allowed_hosts auth auth_rate_limit builtin csp_nonce csrf debug_fragment_validator inject layout_debug protocol security_headers sessions static streaming_html Caret Right Pages actions context debug discovery Caret Right index bus events stream renderer resolve sections shell_actions shell_context types Caret Right Realtime events sse Caret Right Routing params route router Caret Right Security audit decorators lockout passwords urls Caret Right Server Caret Right Debug editor frames render_plan_snapshot renderers request_context styles template_context alpine debug_page debug_runtime delegation dev dev_browser_reload devtools errors fragment_dispatch fragment_targets_debug handler handler_kwargs htmx_debug htmx_safe_target islands negotiation negotiation_oob production route_explorer sender speculation_rules sse_lifecycle sync_handler terminal_checks terminal_errors view_transitions Caret Right Templating adapter composition filters fragment_target_registry integration kida_adapter macros navigation_swap oob_registry render_plan returns streaming suspense trace Caret Right Testing assertions client route_smoke sse Caret Right Tools events handler registry schema Caret Right Validation result rules chirp config context domains errors extraction freeze health live_blocks logging plugin resilience shell_actions shell_regions sources Chirp API ReferenceTemplating ᗢ Caret Down Link Copy URL External Open LLM text Copy Copy LLM text Share with AI Ask Claude Ask ChatGPT Ask Gemini Ask Copilot Module templating.navigation_swap Route-aware boosted navigation swap resolution (hierarchical domains). Pure helpers map (current path, destination path, layout chains) to a recommended hx-target and symbolic scope name. Server rendering still uses HX-Target and FragmentTargetRegistry at runtime; this module only helps authors avoid hand-authoring targets on every link. 1Class10Functions Classes SwapResolution 4 ▼ Recommended swap for a boosted GET navigation. Recommended swap for a boosted GET navigation. Attributes Name Type Description htmx_target str — target_id str — scope str — fragment_block str | None — Functions normalize_route_path 1 str ▼ Normalize a URL path for comparisons (no query or fragment). def normalize_route_path(path: str) -> str Parameters Name Type Description path str Returns str resolve_destination_path 2 str | None ▼ Resolve *href* to an absolute site path, or None if external / unusable. def resolve_destination_path(current_path: str, href: str) -> str | None Parameters Name Type Description current_path str href str Returns str | None common_layout_prefix_len 2 int ▼ Length of the longest common prefix of two layout chains (template-wise). def common_layout_prefix_len(a: LayoutChain, b: LayoutChain) -> int Parameters Name Type Description a LayoutChain b LayoutChain Returns int common_navigation_prefix_len 2 int ▼ Length of the longest common prefix of two navigation-domain paths. def common_navigation_prefix_len(a: LayoutChain, b: LayoutChain) -> int Parameters Name Type Description a LayoutChain b LayoutChain Returns int lookup_layout_chain_for_path 3 LayoutChain | None ▼ Resolve a concrete GET path to its filesystem ``LayoutChain``. def lookup_layout_chain_for_path(path: str, *, router: Any | None, route_layout_chains: Mapping[str, Any]) -> LayoutChain | None Parameters Name Type Description path str router Any | None route_layout_chains Mapping[str, Any] Returns LayoutChain | None pick_navigation_layout_index 2 int | None ▼ Choose the destination layout whose outlet should own the navigation. Rules: -… def pick_navigation_layout_index(*, layout_chain_current: LayoutChain | None, layout_chain_dest: LayoutChain) -> int | None Choose the destination layout whose outlet should own the navigation. Rules: no navigation metadata on either side: keep legacy geometry-only behavior one side annotated, the other not: be conservative and return None same navigation-domain path: use the existing geometry within that domain shared navigation ancestry but diverging child domains: target the last shared navigation boundary in the destination chain Parameters Name Type Description layout_chain_current LayoutChain | None layout_chain_dest LayoutChain Returns int | None pick_outlet_layout_index 3 int ▼ Choose which layout level owns the primary outlet for this transition. def pick_outlet_layout_index(*, nc: int, nd: int, common: int) -> int Parameters Name Type Description nc int nd int common int Returns int concrete_target_id 2 str ▼ Resolve DOM target id (no #) for a layout using scope map and metadata. def concrete_target_id(layout: LayoutInfo, swap_scope_map: Mapping[str, str]) -> str Parameters Name Type Description layout LayoutInfo swap_scope_map Mapping[str, str] Returns str resolve_navigation_swap 6 SwapResolution | None ▼ Return recommended swap metadata for boosted navigation, or None. *destination… def resolve_navigation_swap(*, current_path: str, destination_path: str, layout_chain_current: LayoutChain | None, layout_chain_dest: LayoutChain | None, registry: FragmentTargetRegistry, swap_scope_map: Mapping[str, str]) -> SwapResolution | None Return recommended swap metadata for boosted navigation, or None. destination_path must be normalized (see normalize_route_path()). When the destination has no layout chain, returns None. When current and destination paths are equal, returns None (avoid redundant swaps). Parameters Name Type Description current_path str destination_path str layout_chain_current LayoutChain | None layout_chain_dest LayoutChain | None registry FragmentTargetRegistry swap_scope_map Mapping[str, str] Returns SwapResolution | None make_swap_attrs 4 Any ▼ Build the template global ``swap_attrs(href, *, hx_boost=True)``. def make_swap_attrs(*, route_layout_chains: Mapping[str, Any], router: Any | None, fragment_target_registry: FragmentTargetRegistry, swap_scope_map: Mapping[str, str]) -> Any Parameters Name Type Description route_layout_chains Mapping[str, Any] router Any | None fragment_target_registry FragmentTargetRegistry swap_scope_map Mapping[str, str] Returns Any ← Previous macros Next → oob_registry List Magnifying Glass ESC Recent Clear Magnifying Glass No results for "" Start typing to search... ↑↓ Navigate ↵ Open ESC Close Powered by Lunr ⌁⌁ Magnifying Glass Search X Close Documentation Caret Down Info About Get Started Build Apps Quality and Operations File Text Reference Cube Examples Applied Tutorials Releases Dev Caret Down GitHub Chirp API Reference Forum Palette Appearance Chevron Down Mode Monitor System Sun Light Moon Dark Palette Snow Lynx Brown Bengal Silver Bengal Charcoal Bengal Blue Bengal © 2026 Chirp built in ᓚᘏᗢ { "linkPreviews": { "enabled": true, "hoverDelay": 200, "hideDelay": 150, "showSection": true, "showReadingTime": true, "showWordCount": true, "showDate": true, "showTags": true, "maxTags": 3, "includeSelectors": [".prose"], "excludeSelectors": ["nav", ".toc", ".breadcrumb", ".pagination", ".card", "[class*='-card']", ".tab-nav", "[class*='-widget']", ".child-items", ".content-tiles"], "allowedHosts": [], "allowedSchemes": ["https"], "hostFailureThreshold": 3, "showDeadLinks": true } } window.BENGAL_LAZY_ASSETS = { tabulator: '/chirp/assets/js/tabulator.min.js', dataTable: '/chirp/assets/js/data-table.js', mermaidToolbar: '/chirp/assets/js/mermaid-toolbar.9de5abba.js', mermaidTheme: '/chirp/assets/js/mermaid-theme.344822c5.js', graphMinimap: '/chirp/assets/js/graph-minimap.ff04e939.js', graphContextual: '/chirp/assets/js/graph-contextual.355458ba.js' }; window.BENGAL_ICONS = { close: '/chirp/assets/icons/close.911d4fe1.svg', enlarge: '/chirp/assets/icons/enlarge.652035e5.svg', copy: '/chirp/assets/icons/copy.3d56e945.svg', 'download-svg': '/chirp/assets/icons/download.04f07e1b.svg', 'download-png': '/chirp/assets/icons/image.c34dfd40.svg', 'zoom-in': '/chirp/assets/icons/zoom-in.237b4a83.svg', 'zoom-out': '/chirp/assets/icons/zoom-out.38857c77.svg', reset: '/chirp/assets/icons/reset.d26dba29.svg' }; { "prerender": [ { "where": { "and": [ { "href_matches": "/docs/*" }, { "not": { "selector_matches": "[data-external], [target=_blank], .external" } } ] }, "eagerness": "conservative" } ], "prefetch": [ { "where": { "and": [ { "href_matches": "/*" }, { "not": { "selector_matches": "[data-external], [target=_blank], .external" } } ] }, "eagerness": "conservative" } ] } Arrow Up -------------------------------------------------------------------------------- Metadata: - Word Count: 1338 - Reading Time: 7 minutes