1. Go to this page and download the library: Download dancycodes/gale library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
gale()->navigate('/users');
gale()->navigate('/users', 'main-content');
// Merge query params
gale()->navigateMerge(['page' => 2]);
// Replace history instead of push
gale()->navigateReplace('/users');
// Update query parameters in place
gale()->updateQueries(['sort' => 'name', 'order' => 'asc']);
// Clear specific query parameters
gale()->clearQueries(['filter', 'search']);
// Full page reload
gale()->reload();
gale()->dispatch('user-updated', ['id' => $user->id]);
// Targeted to a specific element
gale()->dispatch('refresh', ['section' => 'cart'], [
'selector' => '.shopping-cart',
]);
gale()->js('console.log("Hello from server")');
gale()->js('myApp.showNotification("Saved!")');
// Update a component's state
gale()->componentState('cart', [
'items' => $cartItems,
'total' => $total,
]);
// Invoke a method on a named component
gale()->componentMethod('cart', 'recalculate');
gale()->componentMethod('calculator', 'setValues', [10, 20, 30]);
// Check if the request is a Gale request
if (request()->isGale()) {
return gale()->state('data', $data);
}
return view('page', compact('data'));
// Access state sent from the Alpine component
$count = request()->state('count', 0);
$email = request()->state('user.email');
// Check if it's a navigation request
if (request()->isGaleNavigate()) {
return gale()->fragment('page', 'content', $data);
}
// Validate state with automatic error response
$validated = request()->validateState([
'email' => '
// Standard validate() -- auto-converts for Gale requests
public function store(Request $request)
{
$request->validate([
'state.name' => 'y
public function store(Request $request)
{
$validated = $request->validateState([
'name' => '
// app/Http/Requests/StoreUserRequest.php
class StoreUserRequest extends FormRequest
{
public function rules(): array
{
return [
'state.name' => ')
{
User::create($request->validated());
return gale()->messages(['_success' => 'Created!']);
}
gale()->when($condition, function ($gale) {
$gale->state('visible', true);
});
gale()->whenGale(
fn($g) => $g->state('partial', true),
fn($g) => $g->web(view('full'))
);
gale()->whenGaleNavigate('sidebar', function ($gale) {
$gale->fragment('layout', 'sidebar', $data);
});
// Web fallback for non-Gale requests
return gale()
->state('data', $data)
->web(view('page', compact('data')));
use Dancycodes\Gale\Routing\Attributes\Route;
use Dancycodes\Gale\Routing\Attributes\Prefix;
use Dancycodes\Gale\Routing\Attributes\Group;
use Dancycodes\Gale\Routing\Attributes\Middleware;
#[Prefix('/admin')]
class UserController extends Controller
{
#[Route('GET', '/users', name: 'admin.users.index')]
public function index() { }
#[Route('GET', '/users/{id}', name: 'admin.users.show')]
public function show($id) { }
}
// Group attribute (prefix + middleware + route name prefix in one)
#[Group(prefix: '/api', middleware: ['auth'], as: 'api.')]
class ApiController extends Controller
{
#[Route('GET', '/data')]
public function data() { }
}
return [
// Default response mode: 'http' (JSON) or 'sse' (Server-Sent Events)
'mode' => env('GALE_MODE', 'http'),
// Intercept dd() and dump() during Gale requests, render in debug panel
'debug' => env('GALE_DEBUG', false),
// Sanitize HTML in gale-patch-elements events (XSS protection)
'sanitize_html' => env('GALE_SANITIZE_HTML', true),
// Allow <script> tags in patched HTML (false = strip scripts)
'allow_scripts' => env('GALE_ALLOW_SCRIPTS', false),
// Inject HTML comment markers for conditional/loop Blade blocks
// Improves morph accuracy; disable in production to reduce payload
'morph_markers' => env('GALE_MORPH_MARKERS', true),
// Content Security Policy nonce: null | 'auto' | '<nonce-string>'
'csp_nonce' => env('GALE_CSP_NONCE', null),
// Security headers added to all Gale responses
'headers' => [
'x_content_type_options' => 'nosniff',
'x_frame_options' => 'SAMEORIGIN',
'cache_control' => 'no-store, no-cache, must-revalidate',
'custom' => [],
],
// Open-redirect prevention
'redirect' => [
'allowed_domains' => [], // e.g. ['payment.stripe.com', '*.myapp.com']
'allow_external' => false,
'log_blocked' => true,
],
// Attribute-based route discovery (opt-in)
'route_discovery' => [
'enabled' => false,
'conventions' => true, // Auto-discover index/show/create/store/edit/update/destroy
'discover_controllers_in_directory' => [
// app_path('Http/Controllers'),
],
'discover_views_in_directory' => [],
'pending_route_transformers' => [
...Dancycodes\Gale\Routing\Config::defaultRouteTransformers(),
],
],
];