inertiajs / inertia-laravel

The Laravel adapter for Inertia.js.
https://inertiajs.com
MIT License
2.01k stars 224 forks source link

Fix Double Url Address Path #576

Closed wiefunkdai closed 5 months ago

wiefunkdai commented 7 months ago

Repair bug for double path url when runtime browse without serve command.

taylordragoo commented 7 months ago

This issue has existed for nearly two years. I wouldn't get your hopes up the devs behind this package have the mental capacity to implement this quick fix.

zevitagem commented 6 months ago

This man implemented a more flexible code that solves this problem, take a look: https://github.com/feature-ninja/inertia-laravel/pull/1

flexponsive commented 5 months ago

Dear @reinink and @claudiodekker, I'm tagging you since you were previously previously involved with the base url / reverse proxy forward prefix issue in Response.php. It seems that "duplicate base url in navigation" is the issue developers run into most frequently with the inertia-laravel adapter: 5 out of 30 open PRs and 3 out of 27 issues are about this issue, as well as lots of discussions on community forums like laracasts and stackoverflow.

The good news is that this problem can be fixed with a one-line change which does not introduce regressions (see this PR or #360 or #566). It would be great if you could consider merging one of these PRs.

Thank you for your amazing work on Inertia!

mikemathewson commented 5 months ago

You can implement this fix in your own project by using Laravel's service container to override Inertia's methods. Not ideal, but if you need this fix right now and don't want to use a forked version then this works well.

namespace App\Providers;

use App\Http\Inertia\ResponseFactory as MyResponseFactory;
use Illuminate\Support\ServiceProvider;
use Inertia\ResponseFactory;

class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->bind(ResponseFactory::class, fn () => new MyResponseFactory);
    }
}
namespace App\Http\Inertia;

use Inertia\ResponseFactory as BaseResponseFactory;

use Illuminate\Contracts\Support\Arrayable;

class ResponseFactory extends BaseResponseFactory
{
    public function render(string $component, $props = []): Response
    {
        if ($props instanceof Arrayable) {
            $props = $props->toArray();
        }

        return new Response(
            $component,
            array_merge($this->sharedProps, $props),
            $this->rootView,
            $this->getVersion()
        );
    }
}
namespace App\Http\Inertia;

use Inertia\Response as BaseResponse;

use Illuminate\Support\Arr;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Response as ResponseFactory;

class Response extends BaseResponse
{
    public function toResponse($request)
    {
        $only = array_filter(explode(',', $request->header('X-Inertia-Partial-Data', '')));

        $props = ($only && $request->header('X-Inertia-Partial-Component') === $this->component)
            ? Arr::only($this->props, $only)
            : array_filter($this->props, static function ($prop) {
                return ! ($prop instanceof LazyProp);
            });

        $props = $this->resolvePropertyInstances($props, $request);
        $requestUri = str_replace($request->getBaseUrl(), '', $request->getRequestUri());

        $page = [
            'component' => $this->component,
            'props' => $props,
            // 'url' => $request->getBaseUrl().$request->getRequestUri(),
            'url' => $request->getBaseUrl().$requestUri,
            'version' => $this->version,
        ];

        if ($request->header('X-Inertia')) {
            return new JsonResponse($page, 200, ['X-Inertia' => 'true']);
        }

        return ResponseFactory::view($this->rootView, $this->viewData + ['page' => $page]);
    }
}
jessarcher commented 5 months ago

Thanks for the PR, and I'm sorry for the delay! I ended up going with a slightly different approach (#592), but this PR was very helpful!