Frontend Navigation

SPA-like navigation with x-navigate and $navigate.

Overview

Alpine Gale provides two ways to trigger navigation from the frontend:

x-navigate

A directive for links and forms. Intercepts clicks/submits and performs Gale navigation.

$navigate

A magic for programmatic navigation. Call it from event handlers or Alpine methods.

The x-navigate Directive

Add x-navigate to links for SPA-style navigation:

<!-- Single link -->
<a href="/posts/123" x-navigate>View Post</a>

<!-- All links in a container -->
<nav x-navigate>
    <a href="/">Home</a>
    <a href="/about">About</a>
    <a href="/contact">Contact</a>
</nav>

Form Navigation

Forms with x-navigate send their data as a Gale navigation request:

<!-- Search form -->
<form action="/search" x-navigate>
    <input type="text" name="q" placeholder="Search...">
    <button type="submit">Search</button>
</form>

<!-- Navigates to /search?q=user-input -->

Skipping Elements

Use x-navigate-skip to exclude specific links from delegation:

<nav x-navigate>
    <a href="/">Home</a>
    <a href="/about">About</a>
    <a href="/logout" x-navigate-skip>Logout</a> <!-- Regular link -->
</nav>

Navigate Keys

Navigate keys identify navigation contexts so the backend can respond appropriately:

<!-- Main content navigation -->
<nav x-navigate.key.content>
    <a href="/posts">All Posts</a>
    <a href="/posts?category=tech">Tech</a>
</nav>

<!-- Sidebar navigation -->
<aside x-navigate.key.sidebar>
    <a href="/categories">Categories</a>
    <a href="/tags">Tags</a>
</aside>

The backend can then use whenGaleNavigate('sidebar') to respond only to sidebar navigation.

Modifiers

Parameter Merging

<!-- Merge with existing query params -->
<a href="/products?sort=price" x-navigate.merge>Sort by Price</a>

<!-- Keep only specific params -->
<a href="/products?page=1" x-navigate.only.category.sort>First Page</a>

<!-- Exclude specific params -->
<a href="/products" x-navigate.except.page>Reset Pagination</a>

History Replace

<!-- Replace history instead of push (back won't return) -->
<a href="/products?view=grid" x-navigate.replace>Grid View</a>

Debounce & Throttle

<!-- Debounce navigation (wait for pause) -->
<form action="/search" x-navigate.debounce.300ms>
    <input type="text" name="q">
</form>

<!-- Throttle navigation (max once per interval) -->
<nav x-navigate.throttle.500ms>
    ...
</nav>

Combining Modifiers

<!-- Merge params, replace history, with a key -->
<a href="/products?sort=price"
   x-navigate.merge.replace.key.filters>
    Sort by Price
</a>

$navigate Magic

Use $navigate for programmatic navigation from Alpine expressions:

<!-- Basic navigation -->
<button @click="$navigate('/posts')">Go to Posts</button>

<!-- With options -->
<button @click="$navigate('/posts?page=2', { merge: true, key: 'pagination' })">
    Next Page
</button>

<!-- Dynamic URL -->
<div x-data="{ selectedId: null }">
    <select x-model="selectedId"
            @change="$navigate(`/posts/${selectedId}`)">
        ...
    </select>
</div>

Available Options

$navigate('/url', {
    key: 'content',      // Navigate key
    merge: true,         // Merge query params
    replace: false,      // Use replaceState
    only: ['a', 'b'],    // Keep only these params
    except: ['page'],    // Exclude these params
})

Browser History

Gale navigation automatically integrates with browser history:

  • Back/Forward buttons work — Gale handles popstate events
  • URL updates — The address bar reflects the current state
  • Shareable links — Users can bookmark and share URLs
Progressive Enhancement
Links work normally if JavaScript fails to load. The href attribute is always respected.

Quick Reference

x-navigate Modifiers

Modifier Description
.key.name Set navigate key for backend filtering
.merge Preserve existing query parameters
.replace Use replaceState instead of pushState
.only.param1.param2 Keep only specified params
.except.param1 Exclude specified params
.debounce.300ms Debounce navigation
.throttle.500ms Throttle navigation

Related Attributes

Attribute Description
x-navigate Enable Gale navigation on element
x-navigate-skip Exclude element from delegated navigation
data-navigate Alternative URL source (when no href)

On this page