inertia-laravel icon indicating copy to clipboard operation
inertia-laravel copied to clipboard

How to use inertia for Laravel app which is hosted under sub url

Open w99910 opened this issue 3 years ago • 1 comments

Hello. I'm trying to host Laravel app behind reverse proxy using Nginx. The routes are working as expected within Laravel routes itself but when I make inertia response, the url is changed.

For example, Let's say there is domain 'my.test' and I wanna host Laravel app under 'my.test/app1'.

nginx.conf

server {
  listen 80;
  listen [::]:80;
  server_name my.test;

  location /app1/ {
    proxy_set_header X-Forwarded-Prefix /app1;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
    proxy_set_header X-Forwarded-Host my.test;
    proxy_set_header X-Forwarded-Port 443;
    proxy_pass http://127.0.0.1:8000/;
   }
}

routes/web.php

Route::get('/', function () {
    return view('welcome');
});

Route::get('/test',function(\Illuminate\Http\Request $request){
   return \Inertia\Inertia::render('test'); // test is vue component.
});

When I access the url http://my.test/app1/, the welcome page is returned under http://my.test/app1/.

But when I access the url http://my.test/app1/test, the vue component named test is returned but only under http://my.test/test. I wanna have it under http://my.test/app1/test. How can I achieve such behavior?

My app dependencies are

  • Laravel Version : ^9.0
  • Vue : ^2.6
  • inertiajs/inertia-laravel: ^0.5.4
  • @inertiajs/inertia: ^0.11.0,
  • @inertiajs/inertia-vue: ^0.8.0,

w99910 avatar Feb 12 '22 11:02 w99910

Hi @w99910 I don't think is related to inertia, but more how Laravel Routing is working.

What is you APP_URL value in .env or in (config/app.php) should be: http://my.test/app1

SergkeiM avatar Feb 28 '22 07:02 SergkeiM

I have prob as well when setting Laravel 10 under sub url as such domain.com/mylaravel but when I open the application it will get redirected to domain.com/mylaravel/mylaravel it happens when the controller return the view using Inertia::render, but no when using regular blade view

Laravel 10, Vue: 3, Inertia, Vite basically it happens on fresh installation of Laravel 10 with starter kit with Vue and Vite on Linux Ubuntu 22.04 and suing apache 2.4.x+

seth-setiadha avatar Jun 14 '23 18:06 seth-setiadha

@seth-setiadha I have figured out a workaround for the time being. I extended the Inertia\Response class mainly and custom Render class instead of \Inertia\Inertia::render(). The following is the code FYI.

<?php

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

class Response extends BaseResponse
{
    protected ?string $rootUrl = null;

    public function setRootUrl(string $url): static
    {
        $this->rootUrl = $url;
        return $this;
    }

    public function toResponse($request): \Illuminate\Http\Response|JsonResponse|\Symfony\Component\HttpFoundation\Response
    {
        $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);

        $page = [
            'component' => $this->component,
            'props' => $props,
            'url' => ($this->rootUrl ?? $request->getBaseUrl()) . $request->getRequestUri(),
            '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]);
    }
}
<?php

use Illuminate\Contracts\Support\Arrayable;
use Inertia\ResponseFactory;

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

        $response = new Response(
            $component,
            array_merge($this->sharedProps, $props),
            $this->rootView,
            $this->getVersion()
        );

        $response->setRootUrl(config('app.url'));

        return $response;
    }
}

w99910 avatar Jun 18 '23 04:06 w99910