Backend Navigation
Control browser navigation and URL updates from your Laravel controllers.
Overview
Gale provides two types of navigation from the backend:
navigate()
Updates URL via pushState. Content morphs reactively without full reload. Great for SPA-like navigation.
redirect()
Full page reload via window.location. Supports session flash data. Traditional Laravel redirect behavior.
The navigate() Method
Use navigate() for SPA-like navigation that updates the URL without a full page reload:
public function show(Post $post)
{
return gale()
->state('post', $post)
->view('posts.show', compact('post'))
->navigate("/posts/{$post->slug}");
}
public function show(Post $post)
{
return gale()
->state('post', $post)
->view('posts.show', compact('post'))
->navigate("/posts/{$post->slug}");
}
Navigate Keys
Navigate keys let you identify different navigation contexts. The frontend can respond differently based on the key:
// Navigate with a key
return gale()
->fragment('posts.index', 'main-content', compact('posts'))
->navigate('/posts?page=2', 'content');
// Navigate sidebar separately
return gale()
->fragment('layout', 'sidebar', compact('categories'))
->navigate('/posts', 'sidebar');
// Navigate with a key
return gale()
->fragment('posts.index', 'main-content', compact('posts'))
->navigate('/posts?page=2', 'content');
// Navigate sidebar separately
return gale()
->fragment('layout', 'sidebar', compact('categories'))
->navigate('/posts', 'sidebar');
Query Parameters
Merging Parameters
Use navigateMerge() to preserve existing query parameters:
// Current URL: /products?category=shoes&sort=price
return gale()
->view('products.index', compact('products'))
->navigateMerge('/products?page=2');
// Result: /products?category=shoes&sort=price&page=2
// Current URL: /products?category=shoes&sort=price
return gale()
->view('products.index', compact('products'))
->navigateMerge('/products?page=2');
// Result: /products?category=shoes&sort=price&page=2
Clean Navigation
Use navigateClean() to clear existing parameters:
// Clear filters and start fresh
return gale()
->view('products.index', compact('products'))
->navigateClean('/products');
// Clear filters and start fresh
return gale()
->view('products.index', compact('products'))
->navigateClean('/products');
Selective Parameters
Keep only specific parameters with navigateOnly():
// Keep only 'category' and 'sort', drop others
return gale()
->navigateOnly('/products?page=1', ['category', 'sort']);
// Or exclude specific parameters
return gale()
->navigateExcept('/products', ['page', 'cursor']);
// Keep only 'category' and 'sort', drop others
return gale()
->navigateOnly('/products?page=1', ['category', 'sort']);
// Or exclude specific parameters
return gale()
->navigateExcept('/products', ['page', 'cursor']);
Query-Only Navigation
Update just the query string while keeping the current path:
// Add/update query params on current page
return gale()
->state('sort', 'price')
->navigateQueries(['sort' => 'price']);
// Clear specific queries
return gale()
->clearQueries(['page', 'search']);
// Add/update query params on current page
return gale()
->state('sort', 'price')
->navigateQueries(['sort' => 'price']);
// Clear specific queries
return gale()
->clearQueries(['page', 'search']);
History Mode
By default, navigate() uses pushState which adds an entry to browser history.
Use navigateReplace() to update the URL without adding history:
// Replace current history entry (back button won't return here)
return gale()
->view('products.index', compact('products'))
->navigateReplace('/products?sort=price');
// Replace current history entry (back button won't return here)
return gale()
->view('products.index', compact('products'))
->navigateReplace('/products?sort=price');
When to Use replaceState
navigateReplace() for filter changes, sort order updates, or any navigation where going "back" to the intermediate state doesn't make sense.
Full-Page Redirects
Use redirect() when you need a full page reload with Laravel session flash data:
public function store()
{
$post = Post::create(request()->state());
return gale()
->redirect("/posts/{$post->id}")
->with('success', 'Post created!');
}
public function store()
{
$post = Post::create(request()->state());
return gale()
->redirect("/posts/{$post->id}")
->with('success', 'Post created!');
}
Redirect Methods
// Redirect to a named route
return gale()
->redirect('/')
->route('posts.show', ['post' => $post])
->with('success', 'Saved!');
// Redirect back
return gale()
->redirect('/')
->back('/')
->withErrors($errors)
->withInput();
// Redirect to home
return gale()
->redirect('/')
->home();
// Redirect to intended (after login)
return gale()
->redirect('/')
->intended('/dashboard');
// Refresh current page
return gale()
->redirect('/')
->refresh(preserveQuery: true);
// Force reload (bypasses cache)
return gale()
->redirect('/')
->forceReload(true);
// Redirect to a named route
return gale()
->redirect('/')
->route('posts.show', ['post' => $post])
->with('success', 'Saved!');
// Redirect back
return gale()
->redirect('/')
->back('/')
->withErrors($errors)
->withInput();
// Redirect to home
return gale()
->redirect('/')
->home();
// Redirect to intended (after login)
return gale()
->redirect('/')
->intended('/dashboard');
// Refresh current page
return gale()
->redirect('/')
->refresh(preserveQuery: true);
// Force reload (bypasses cache)
return gale()
->redirect('/')
->forceReload(true);
When to Use Each
| Use Case | Method | Why |
|---|---|---|
| Pagination, filters, search | navigate() |
Fast updates, no reload needed |
| View details, tab navigation | navigate() |
SPA-like experience |
| After login/logout | redirect() |
Session state changes |
| After form submission | redirect() |
Flash messages, prevent resubmit |
| External URLs | redirect() |
Same-domain restriction on navigate |
Quick Reference
| Method | Description |
|---|---|
navigate($url, $key) |
Update URL via pushState |
navigateMerge($url, $key) |
Navigate preserving existing params |
navigateClean($url, $key) |
Navigate clearing existing params |
navigateOnly($url, $only, $key) |
Keep only specified params |
navigateExcept($url, $except, $key) |
Remove specified params |
navigateReplace($url, $key) |
Update URL via replaceState |
navigateQueries($queries) |
Update only query params |
clearQueries($keys) |
Remove specific query params |
redirect($url) |
Full page redirect with flash support |
redirect()->route($name) |
Redirect to named route |