inertia-laravel
inertia-laravel copied to clipboard
Laravel Inertia apps doesn't support subdomain redirects
I'm working on a Laravel 9, InertiaJS and vue project where a user can submit a new product through products/create
route and this sends to ProductController@store which does all what it's supposed to do and then supposedly redirect the user to the newly created product on a subdomain route like this http://username.example.test/my-new-product
The issue I'm having is that I keep getting the below error and the redirect doesn't work:
Access to XMLHttpRequest at 'http://user.example.test/my-first-product' (redirected from 'http://example.test/products/create') from origin 'http://example.test' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
The code works as follows:
1- The form:
const form = useForm("createProduct", {
webshop_id: null,
title: null,
price: null,
type: null,
currency: null,
description: null,
thumbnail: null,
});
const submit = () => {
form.post(route("products.create"), {
onSuccess: () => form.reset(),
});
};
2- Products create router:
Route::middleware([
'auth:sanctum',
config('jetstream.auth_session'),
'verified',
])->group(function () {
Route::post('products/create', [ProductController::class, 'store'])->name('products.create');
});
3- The controller - Storing the new product with user details and redirecting (which doesn't work) to show the product
public function store(StoreProductRequest $request)
{
// Code
return redirect()->route('products.show', [$user, $product]);
}
4- The show route and controller@show
Route::domain('{user:username}.' . env('APP_URL'))->group(function () {
Route::get('{product:slug}', [ProductController::class, 'show'])->name('products.show');
});
public function show(User $user, Product $product)
{
return Inertia::render('Products/Show', [
'user' => $user,
'product' => $product,
'thumbnails' => $product->productimages
]);
}
I saw @reinink explain in this Issue that we can use now Inertia::location
The only way I could get this to work is returning this is the ProductController@store:
return Inertia::location('http://' . $user->username . '.example.test/' . $validated['slug']);
But It causes a full page refresh which defeats the whole concept of having a single page application and I will have to remember changing 'http' to 'https' and domain to the real domain when I'm going to put the app in production. I was hoping that I was doing something wrong but after hours of searching for a solution I began to think that Laravel Inertia apps doesn't support subdomain redirects
Solved the issue by making the below changes to cors.php
'paths' => ['api/*', '*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => ['x-inertia'],
'max_age' => 0,
'supports_credentials' => false,
No cors issues now but I'm having a different issue where the desired page rendered by Inertia on the incorrect route. Raised the Issue for Laravel Framework
This is driving me crazy! Subdomains isn't working even if I hard set the redirect like this redirect()->to('http://username.example.test/productSlug') it gives me in the browser url example.test/productSlug only. I even used Inertia to redirect from the frontend to a url and did the same. The only thing that works is using Inertia::location() but this causes a full page refresh.
Same behavior occurs with Inertia's Link
.
If you are on a subdomain route like {subdomain}.example.test/profile
and you have a link like this <Link href="http://example.test">Click</Link>
It will redirect you to {subdomain}.example.test
. The only workaround is having a normal HTML anchor tag like this <a href="http://example.test">Click</a>
Javascript's pushState
cannot change the domain
@MooseSaeed Hey I honestly don't think this is possible to make Inertia requests across subdomains — sorry!
@reinink I agree! After days of research I'm sure now that it is impossible to route redirect to a subdomain route from root domain without page refresh. Any change to the host will require the page to reload which is out of Laravel and JetStream scope and out of InertiaJS hands. As far as I understand that this is for security purposes.
Sorry for wasting your time and thanks a million for your efforts
Yes inertia works with browser history, but it seems inertia is missing a check, so that redirects to a different domain are handled correctly and reload the page
@MooseSaeed As a workaround you can add to your HandleInertiaRequests middleware
public function version(Request $request): string
{
return md5($request->host) . parent::version($request);
}
And if you have CORS working, the request will be followed and inertia will reload the page but you'll have one more request than what is strictly necessary
Cross domains redirects are not very frequent so you'd be better doing it explicitely without inertia using a window.location and it would prevent all the CORS issues that goes with it
If you need the domain to be dynamic, instead of a redirect then send the url as an inertia prop and use that in the success handler for your window.location
@reinink sorry to bother, but question, that is not covered in docs/thread and related to current issue.
Is using <a>
tag to get to the subdomain route a viable/good practice for Inertia? E.g. little js component, that checks, if subdomain changes and renders <InertiaLink>
or <a>
.
It's the same app, same cookie name, subdomains due to SEO-stuff.
Cause I don't see any issues with that, but would like not to face any long-term.
Just found this issue as i was having issues with the same thing, is there any chance sub domain redirects can be added to inertia? Would be a great help!
Hey there,
We're closing this issue because it's inactive, already solved, old or not relevant anymore. Feel to open up a new issue if you're still experiencing this problem.
Just came across this issue and, like @riabiy-denis, I solved it via a small component that either outputs an a
tag or an Inertia Link
component by comparing the current host with the host of the link. Works really well and was easy to implement!