Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1.x] Make inertia response more extension friendly #632

Open
wants to merge 7 commits into
base: 1.x
Choose a base branch
from

Conversation

VicGUTT
Copy link

@VicGUTT VicGUTT commented May 29, 2024

This PR simply aims to make Inertia\Response more friendly to extension/customization by:

This unlocks, for example, customizing how the page.url get's resolved by Inertia.

In a particular case, it was necessary for me to ensure redirections keept the url fragment (/abc#123).

Previously I had to:

  • create a custom middleware
  • render the Inertia response
  • get it's orginal content
  • modify it
  • finally reset the page with the modified content
  • return the response.
Example implementation
<?php

declare(strict_types=1);

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;

final class EnsureCorrectInertiaRedirectionWhenPossible
{
    /**
     * Handle an incoming request.
     * Ensure URL fragments on redirections are set whenever possible.
     *
     * @param  Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse)  $next
     */
    public function handle(Request $request, Closure $next): Response|RedirectResponse|JsonResponse
    {
        if (!$request->inertia()) {
            return $next($request);
        }

        $requestedFrom = $request->headers->get('x-requested-from');

        if (!$requestedFrom) {
            return $next($request);
        }

        $response = $next($request);

        if (!($response instanceof JsonResponse)) {
            return $response;
        }

        $parsedRequestedFrom = parse_url($requestedFrom);

        if (!is_array($parsedRequestedFrom)) {
            return $response;
        }

        if (!isset($parsedRequestedFrom['path'])) {
            return $response;
        }

        if (!isset($parsedRequestedFrom['fragment'])) {
            return $response;
        }

        $requestedFromUri = $parsedRequestedFrom['path'] . (
            isset($parsedRequestedFrom['query']) ? "?{$parsedRequestedFrom['query']}" : ''
        );

        $page = $response->getOriginalContent();

        if ($requestedFromUri !== $page['url']) {
            return $response;
        }

        $page['url'] = "{$page['url']}#{$parsedRequestedFrom['fragment']}";

        $response->setData($page);

        return $response;
    }
}

Now, a custom Response class overwritting the resolveUrl method could be resolved from the container whenever an Inertia response is returned.

Example implementation
use Illuminate\Http\Request;
use Illuminate\Foundation\Application;
use Illuminate\Support\ServiceProvider;
use Inertia\Response as InertiaResponse;

final class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        $this->app->bind(InertiaResponse::class, CustomInertiaResponse::class);
    }
}


final class CustomInertiaResponse extends InertiaResponse
{
    public function resolveUrl(Request $request, array $props): string
    {
        $url = '...';

        return $url;
    }
}

@driesvints driesvints changed the title [1.x] - Make inertia response more extension friendly [1.x] Make inertia response more extension friendly May 29, 2024
@VicGUTT
Copy link
Author

VicGUTT commented Jun 13, 2024

Resolved any conflicts that arose after #641. This PR is now up to date with the 1.x branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant