Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ajax Bundle Laravel Package

xi/ajax-bundle

xi/ajax-bundle offers a lightweight AJAX layer for PHP applications, simplifying asynchronous request handling and JSON responses. It cuts boilerplate for AJAX endpoints and integrates cleanly with existing controllers, making it a simple, dependency-light toolkit for small projects.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first: xi/ajax-bundle is a Symfony 2 bundle, not a Laravel package. It predates modern PSR-4 conventions and targets PHP 5.3/5.4-era Symfony. If you're in a Laravel codebase, you will not install this — Laravel's $request->expectsJson() / $request->ajax() plus response()->json() already cover the same ground. The useful way to read this package as a Laravel developer is as a reference for how a framework-agnostic "respond with JSON when the client asked for it" helper can be structured, and as a warning about tight coupling to one framework's kernel.

If you find yourself in a legacy Symfony 2 app that already depends on it:

  1. composer require xi/ajax-bundle (expect old symfony/symfony constraints to fight with anything modern; you'll likely need --ignore-platform-reqs or a pinned composer).
  2. Register the bundle in app/AppKernel.php inside registerBundles().
  3. Look first at the bundle's DependencyInjection/ config and its controller helper/service — that service is the entry point. Then read its exception listener, which is where the "return JSON errors instead of HTML pages for AJAX requests" behaviour lives.
  4. First use case: a controller action that returns either a rendered template (normal request) or a JSON envelope (AJAX request) from the same action, without branching boilerplate.

The Laravel translation of the first use case:

public function index(Request $request)
{
    $data = ['items' => Item::all()];

    if ($request->expectsJson()) {
        return response()->json(['ok' => true, 'data' => $data]);
    }

    return view('items.index', $data);
}

That is the entire value proposition of xi/ajax-bundle, minus the bundle ceremony.

Implementation Patterns

1. Content negotiation instead of a boolean flag. The bundle's core idea is: inspect the request (typically X-Requested-With: XMLHttpRequest and/or Accept: application/json) and pick a representation. In Laravel, prefer expectsJson() over ajax() — ajax() only checks X-Requested-With (jQuery-era), while expectsJson() also honours Accept. This matters for fetch/axios clients that don't send the XHR header.

2. Consistent response envelope. If you're porting the bundle's pattern, define one envelope shape and stick to it. The bundle wraps payloads so the front end can branch on a single field:

// app/Http/Responses/ApiResponse.php
class ApiResponse
{
    public static function ok(mixed $data = null, int $status = 200): JsonResponse
    {
        return response()->json(['ok' => true, 'data' => $data, 'error' => null], $status);
    }

    public static function fail(string $message, int $status = 422, array $errors = []): JsonResponse
    {
        return response()->json(['ok' => false, 'data' => null, 'error' => ['message' => $message, 'fields' => $errors]], $status);
    }
}

3. Exception-to-JSON conversion. The bundle's listener is the analogue of Laravel's App\Exceptions\Handler::render() / shouldReturnJson(). Laravel already returns JSON automatically when expectsJson() is true, so the pattern to replicate is shaping it:

// bootstrap/app.php (Laravel 11) or Handler::register()
->withExceptions(function (Exceptions $exceptions) {
    $exceptions->render(function (ValidationException $e, Request $request) {
        if ($request->expectsJson()) {
            return ApiResponse::fail('Validation failed', 422, $e->errors());
        }
    });
})

4. Form/controller split. Rather than a base controller trait (the bundle's approach), keep responses in a dedicated layer — a RespondsWithJson trait, a response factory, or API Resources (JsonResource::collection(...)) if you're returning models. This avoids the bundle's main structural weakness: forcing every controller to inherit from a specific base class.

5. Blade + JSON from the same endpoint. Useful for progressively enhanced pages: let the same route serve HTML to browsers and JSON to scripts, branching only on expectsJson(). Do not put this branching in every action — centralise it in a middleware or a small respond() helper on a base controller.

Gotchas and Tips

  • Abandoned / unmaintained. 5 stars, 0 dependents, Symfony 2-era. Treat it as a case study, not a dependency. Composer will almost certainly refuse to resolve it against Laravel or modern Symfony.
  • X-Requested-With is not reliable. The bundle (and $request->ajax()) trusts a header that modern clients often omit. Always prefer Accept: application/json content negotiation (expectsJson()), and be explicit in your API clients.
  • JSON responses and CSRF. Ajax POSTs still need the CSRF token. In Laravel, use VerifyCsrfToken's except for stateless API routes or send X-CSRF-TOKEN / _token. The bundle doesn't solve this; expect to wire it yourself.
  • Error handling diverges from HTML paths. The most common bug when replicating this pattern: exceptions thrown inside an AJAX branch still render the HTML error page because the request's Accept header wasn't set. Debug by logging $request->header('Accept') and $request->expectsJson() at the top of the action.
  • Don't leak debug pages into JSON. In APP_DEBUG=true, Laravel's whoops-style output is HTML. If you're consuming your own API from JS, either accept Accept: application/json on every call or assert expectsJson() in your exception renderer.
  • Extension point to copy: the bundle's exception listener is a clean pattern. In Laravel, $exceptions->render(...) callbacks and Responsable classes give you the same hook with better ergonomics.
  • Envelope discipline beats cleverness. A consistent {ok, data, error} (or Laravel's native {data, errors} from Resources) beats per-endpoint ad-hoc shapes when you're debugging in the browser network tab and writing front-end handlers.
  • Migration path off the bundle: if you're actually moving a Symfony 2 app to Laravel, the mechanical translation is: bundle helper → expectsJson(); bundle JSON response factory → response()->json() or Resources; bundle exception listener → Exceptions::render in bootstrap/app.php. No bundle required.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource