PHPackages                             quonain/smart-response - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. quonain/smart-response

ActiveLibrary[Templating &amp; Views](/categories/templating)

quonain/smart-response
======================

Unified API and Web response handling for Laravel — detect JSON vs HTML and respond automatically from one controller.

v1.1.1(2w ago)08MITPHPPHP ^8.2CI passing

Since May 21Pushed 2w agoCompare

[ Source](https://github.com/quonainejaz-official/smart-response)[ Packagist](https://packagist.org/packages/quonain/smart-response)[ RSS](/packages/quonain-smart-response/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (10)Versions (5)Used By (0)

SmartResponse
=============

[](#smartresponse)

[![Latest Version on Packagist](https://camo.githubusercontent.com/45ffdb654c5d15deaf33cca374d8b05baa9457f6cfa1ba9384cf470983bb7683/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f71756f6e61696e2f736d6172742d726573706f6e73652e737667)](https://packagist.org/packages/quonain/smart-response)[![License](https://camo.githubusercontent.com/dc650a755e0a8dcdc03979a7190b136dc98e0690c7c8b76d135b5b5922f2d5df/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f71756f6e61696e2f736d6172742d726573706f6e73652e737667)](https://packagist.org/packages/quonain/smart-response)[![PHP Version](https://camo.githubusercontent.com/9d5c4635fe353f32c38c911b1d51841bb882e3cf9172c3a48dc925dc9c8fd39a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f71756f6e61696e2f736d6172742d726573706f6e73652e737667)](https://packagist.org/packages/quonain/smart-response)

**SmartResponse** is a production-ready Laravel package that returns **API JSON** or **Blade / Inertia web views** from the **same controller method** — with automatic request-type detection.

---

Table of contents
-----------------

[](#table-of-contents)

- [Features](#features)
- [Requirements](#requirements)
- [Installation](#installation)
- [Quick start](#quick-start)
- [How API vs Web is detected](#how-api-vs-web-is-detected)
- [Usage](#usage)
    - [Unified response](#unified-smartresponse)
    - [HTTP shortcuts](#http-shortcuts)
    - [Facade &amp; helpers](#facade--global-helpers)
    - [Response macros](#response-macros)
    - [Pagination](#pagination)
    - [API meta enrichment](#api-meta-enrichment)
    - [Rate limiting](#rate-limiting)
    - [Caching](#caching-api)
- [Exception handling](#exception-handling-api)
- [Configuration](#configuration)
- [Middleware &amp; events](#middleware)
- [Testing](#testing)
- [Changelog &amp; license](#changelog)

---

Features
--------

[](#features)

CategoryCapabilities**Detection**`Accept` header, `expectsJson()`, `/api/*` routes, **Bearer tokens** (Sanctum / Passport)**API**Standard JSON envelope, optional XML, validation errors, exception handler**Web**Blade views, redirects, session flash, optional toast**Pagination**Length-aware, simple, **cursor** paginators + API Resources**DX**Trait, Facade, global helpers, `response()->smart*` macros**HTTP shortcuts**`created`, `noContent`, `notFound`, `unauthorized`, `forbidden`**Meta**Auto `timestamp`, `request_id`, optional `api_version` on API responses**Extras**Inertia.js, Livewire, i18n, caching, logging, events, OpenAPI examples**Framework**Laravel **10 · 11 · 12 · 13** · PHP **8.2+**---

Requirements
------------

[](#requirements)

- PHP `^8.2`
- Laravel `^10.0` · `^11.0` · `^12.0` · `^13.0`

---

Installation
------------

[](#installation)

```
composer require quonain/smart-response
```

Or pin the latest 1.x release:

```
composer require quonain/smart-response:^1.1
```

Laravel **auto-discovers** the service provider — no manual registration.

### Publish assets

[](#publish-assets)

```
# Configuration
php artisan vendor:publish --tag=smart-response-config

# Translations
php artisan vendor:publish --tag=smart-response-lang
```

> **Packagist:** After a new release, open your [package page](https://packagist.org/packages/quonain/smart-response) and click **Update** if Composer does not see the latest tag yet. Enable the GitHub hook under package settings for automatic sync.

---

Quick start
-----------

[](#quick-start)

### 1. Add the trait

[](#1-add-the-trait)

```
use Illuminate\Http\Request;
use Quonain\SmartResponse\Traits\HasSmartResponse;

class UserController extends Controller
{
    use HasSmartResponse;

    public function index(Request $request)
    {
        $users = User::paginate(15);

        return $this->smartResponse(
            request: $request,
            data: UserResource::collection($users),
            view: 'users.index',
            message: 'users.fetched', // translation key (optional)
        );
    }

    public function store(Request $request)
    {
        $user = User::create($request->validated());

        return $this->smartCreated($user, 'users.created');
    }
}
```

Request typeResultAPI (`Accept: application/json`, `/api/*`, Bearer token, …)Standard JSONWeb (`text/html`, normal browser)Blade view `users.index` with `$data`, `$message`, …### 2. Default JSON shape

[](#2-default-json-shape)

```
{
  "success": true,
  "message": "Users fetched successfully",
  "data": [],
  "meta": {
    "timestamp": "2026-05-21T12:00:00+00:00",
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "current_page": 1,
    "per_page": 15,
    "total": 100
  },
  "errors": null
}
```

---

How API vs Web is detected
--------------------------

[](#how-api-vs-web-is-detected)

SmartResponse treats a request as **API** when any of these match (configurable in `config/smart-response.php`):

1. `Accept` contains `application/json` or `application/vnd.api+json`
2. `Accept` contains `application/xml` or `text/xml`
3. Route matches `api/*` or configured prefixes (`api` by default)
4. Laravel `expectsJson()` is true (AJAX, etc.)
5. **`Authorization: Bearer …` is present** (`detection.bearer_as_api` — ideal for Sanctum / Passport SPA or mobile apps)

Otherwise the request is handled as **Web** (view or redirect).

---

Usage
-----

[](#usage)

### Unified `smartResponse()`

[](#unified-smartresponse)

```
return $this->smartResponse(
    request: $request,
    data: $data,
    view: 'users.index',
    viewData: ['title' => 'Users'],
    message: 'Success',
    success: true,
    errors: null,
    meta: ['custom' => 'value'],
    status: 200,
    route: 'users.index',       // web redirect
    routeParameters: [],
    format: null,               // auto: json | xml
    flash: true,
    toast: false,
    cacheKey: null,
    cacheTtl: null,
    headers: ['X-Custom' => '1'],
    inertiaComponent: 'Users/Index',
    useInertia: false,
    useLivewire: false,
);
```

### HTTP shortcuts

[](#http-shortcuts)

Trait methodFacade / ManagerStatusUse case`smartSuccess()``SmartResponse::success()`200OK with data`smartCreated()``SmartResponse::created()`201Resource created`smartNoContent()``SmartResponse::noContent()`204Delete / empty OK`smartError()``SmartResponse::error()`4xx/5xxGeneric error`smartNotFound()``SmartResponse::notFound()`404Missing resource`smartUnauthorized()``SmartResponse::unauthorized()`401Not logged in`smartForbidden()``SmartResponse::forbidden()`403No permission`smartValidationError()``SmartResponse::validationError()`422Form / API validation```
return $this->smartSuccess($users, 'Users loaded');
return $this->smartCreated($user, 'users.created');
return $this->smartNoContent();
return $this->smartNotFound('error.not_found');
return $this->smartUnauthorized();
return $this->smartForbidden('error.forbidden');
return $this->smartValidationError($validator->errors());
```

### Facade &amp; global helpers

[](#facade--global-helpers)

```
use Quonain\SmartResponse\Facades\SmartResponse;

SmartResponse::success($data, 'Done');
SmartResponse::created($data, 'Created');
SmartResponse::notFound('Not found');

// Global helpers (no trait required)
smart_response(request: $request, data: $users, view: 'users.index');
smart_created($user, 'users.created');
smart_not_found('error.not_found');
smart_rate_limit_response(retryAfter: 60);
```

### Response macros

[](#response-macros)

```
response()->smart($data, 'OK');
response()->smartSuccess($data, 'Saved');
response()->smartError('Failed', ['code' => 'X'], 400);
response()->smartCreated($data, 'Created');
response()->smartNotFound('Not found');
```

### Pagination

[](#pagination)

**Length-aware** — pass a paginator; meta keys are merged automatically:

```
return $this->smartResponse(
    request: $request,
    data: User::paginate(20),
    view: 'users.index',
);
```

**Cursor** — works with `cursorPaginate()`:

```
return $this->smartResponse(
    request: $request,
    data: User::orderBy('id')->cursorPaginate(15),
);
```

Meta includes: `per_page`, `path`, `next_cursor`, `prev_cursor`, `has_more`.

### API Resources &amp; XML

[](#api-resources--xml)

```
// API Resource collection
return $this->smartResponse(
    request: $request,
    data: UserResource::collection($users),
    view: 'users.index',
);

// Force or auto-detect XML
return $this->smartResponse(request: $request, data: $users, format: 'xml');
```

### API meta enrichment

[](#api-meta-enrichment)

Enabled by default (`meta.enabled` in config). Every API response can include:

Meta keySource`timestamp`Current time (ISO 8601)`request_id``X-Request-Id` header or auto UUID`api_version``X-API-Version` header or `meta.api_version` config```
// config/smart-response.php
'meta' => [
    'enabled' => true,
    'include_timestamp' => true,
    'include_request_id' => true,
    'request_id_header' => 'X-Request-Id',
    'include_api_version' => true,
    'api_version' => '1.0',
],
```

### Rate limiting

[](#rate-limiting)

Returns a standard error JSON with **`Retry-After`** header:

```
// Uses config defaults (429 + retry_after_seconds)
return smart_rate_limit_response();

// Custom message and seconds
return smart_rate_limit_response('Slow down', 120);
```

### Caching (API)

[](#caching-api)

Enable in config, then cache GET API responses:

```
return $this->smartResponse(
    request: $request,
    data: $expensiveData,
    cacheKey: 'users.index',
    cacheTtl: 120,
);
```

Without `cacheKey`, a hash of the full URL + `Accept` header is used.

### Web redirect with flash &amp; toast

[](#web-redirect-with-flash--toast)

```
return $this->smartResponse(
    request: $request,
    message: 'User created',
    route: 'users.index',
    toast: true,
    status: 201,
);
```

---

Exception handling (API)
------------------------

[](#exception-handling-api)

Register in `bootstrap/app.php` (Laravel 11+):

```
use Quonain\SmartResponse\Exceptions\Handler\SmartResponseExceptionHandler;

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->render(function (Throwable $e, $request) {
        return app(SmartResponseExceptionHandler::class)->render($request, $e);
    });
})
```

API requests receive the same JSON envelope; web requests fall through to Laravel’s default handling.

---

Configuration
-------------

[](#configuration)

Publish `config/smart-response.php` and adjust:

KeyDescription`api.*`JSON keys: `success`, `message`, `data`, `meta`, `errors``detection.*`JSON/XML accepts, route prefixes, **`bearer_as_api`**`meta.*`Timestamp, request ID, API version injection`default_format``json` or `xml``status_codes.*`Defaults for 200, 201, 204, 401, 403, 404, 422, 429, 500`web.*`Flash / toast session keys, default redirect route`inertia.enabled`Inertia.js adapter`livewire.enabled`Livewire hooks`locale.enabled`Translate message keys via lang files`cache.enabled`Cache GET API responses`logging.enabled`Log each response`events.enabled``SmartResponsePreparing` / `SmartResponsePrepared``rate_limit.*`429 message and `retry_after_seconds``graphql.enabled`GraphQL response `Accept` detection### Multi-language messages

[](#multi-language-messages)

```
return $this->smartResponse(message: 'users.fetched');
// → lang/vendor/smart-response/en/messages.php
```

Built-in keys include: `users.fetched`, `users.created`, `error.not_found`, `error.unauthorized`, `error.forbidden`, `error.rate_limit`, and more.

### Inertia.js

[](#inertiajs)

```
// config/smart-response.php
'inertia' => ['enabled' => true],

return $this->smartResponse(
    request: $request,
    data: $users,
    inertiaComponent: 'Users/Index',
    useInertia: true,
);
```

---

Middleware
----------

[](#middleware)

Alias: `smart.response` (enabled by default)

```
Route::middleware('smart.response')->group(function () {
    // ...
});
```

### Events

[](#events)

```
use Quonain\SmartResponse\Events\SmartResponsePreparing;
use Quonain\SmartResponse\Events\SmartResponsePrepared;

Event::listen(SmartResponsePreparing::class, fn ($e) => /* mutate payload */);
Event::listen(SmartResponsePrepared::class, fn ($e) => /* inspect response */);
```

### OpenAPI / Swagger

[](#openapi--swagger)

```
use Quonain\SmartResponse\Support\OpenApiExample;

OpenApiExample::successExample();
OpenApiExample::errorExample();
```

---

Testing
-------

[](#testing)

```
composer install
composer test
```

---

Package structure
-----------------

[](#package-structure)

```
smart-response/
├── config/smart-response.php
├── lang/en/messages.php
├── src/
│   ├── Contracts/
│   ├── Detectors/          # API vs Web detection
│   ├── DTO/
│   ├── Formatters/         # JSON, XML
│   ├── Builders/
│   ├── Services/
│   ├── Traits/             # HasSmartResponse
│   ├── Facades/
│   ├── Events/
│   ├── Exceptions/
│   ├── Http/Middleware/
│   ├── Macros/
│   └── Support/            # MetaEnricher, Pagination, i18n, …
├── tests/
├── examples/
└── README.md

```

---

Changelog
---------

[](#changelog)

See [CHANGELOG.md](CHANGELOG.md) for version history (`1.1.0` — HTTP shortcuts, meta enrichment, cursor pagination, Bearer detection).

---

Contributing
------------

[](#contributing)

See [CONTRIBUTING.md](CONTRIBUTING.md).

---

License
-------

[](#license)

MIT © [Quonain Ejaz](https://github.com/quonainejaz-official). See [LICENSE](LICENSE).

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance96

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

4

Last Release

18d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/70b093a198d2194771781d26f9f52a9b063f5ce205e5b931455c92930faf4290?d=identicon)[Quonain Ejaz](/maintainers/Quonain%20Ejaz)

---

Tags

responsejsonapilaravelbladelivewireinertiasmart-response

###  Code Quality

TestsPest

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/quonain-smart-response/health.svg)

```
[![Health](https://phpackages.com/badges/quonain-smart-response/health.svg)](https://phpackages.com/packages/quonain-smart-response)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3325.1M337](/packages/psalm-plugin-laravel)[tallstackui/tallstackui

TallStackUI is a powerful suite of Blade components that elevate your workflow of Livewire applications.

719160.4k12](/packages/tallstackui-tallstackui)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9732.3M121](/packages/roots-acorn)[pressbooks/pressbooks

Pressbooks is an open source book publishing tool built on a WordPress multisite platform. Pressbooks outputs books in multiple formats, including PDF, EPUB, web, and a variety of XML flavours, using a theming/templating system, driven by CSS.

45344.0k1](/packages/pressbooks-pressbooks)[laravel/cashier

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

2.5k28.4M134](/packages/laravel-cashier)[moonshine/moonshine

Laravel administration panel

1.3k239.9k72](/packages/moonshine-moonshine)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
