Reputation: 62
I'm using Ziggy routes in my Laravel (Inertia/Vue3) site. I'm using Server Side Rendering. The routes work fine when Javscript is enabled. The routes don't work when Javascript is disabled or when a search engine tries to crawl the site.
You can see an example here: https://kitcollect.com/register.
If you mouse over the "Already registered" link with javascript enabled, you'll see the url "https://kitcollect.com/register/login".
If you click the link with Javascript enabled, you get redirected to "https://kitcollect.com/login" , as you should. If you disable javacript and click the link, it sends you to "https://kitcollect.com/register/login". It treats the link like a relative link.
My component is generating that link using the following:
<Link
:href="route('login')"
class="underline text-sm text-gray-600 hover:text-gray-900 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
>
Already registered?
</Link>
The login route it's referencing is the standard Laravel login route: Route::get('login', [AuthenticatedSessionController::class, 'create']) ->name('login');
This is what my HandleInertiaRequests middleware looks like:
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Inertia\Middleware;
use Auth;
use Tightenco\Ziggy\Ziggy;
class HandleInertiaRequests extends Middleware
{
/**
* The root template that is loaded on the first page visit.
*
* @var string
*/
protected $rootView = 'app';
/**
* Determine the current asset version.
*/
public function version(Request $request): string|null
{
return parent::version($request);
}
/**
* Define the props that are shared by default.
*
* @return array<string, mixed>
*/
public function share(Request $request): array
{
$ziggy = new Ziggy($group=null, $request->url());
return [
...parent::share($request),
'auth' => [
'auth_user' => $request->user(),
'user'=>\App\Models\User::with('wishlist')->find(Auth::id())
],
'flash'=>[
'success'=>fn()=>$request->session()->get('success'),
'error'=>fn()=>$request->session()->get('error')
],
'ziggy'=>$ziggy->toArray()
];
}
}
My app.js
import './bootstrap';
import '../css/app.css';
import { createSSRApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/vue3';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import { ZiggyVue } from '../../vendor/tightenco/ziggy/dist/vue.m';
const appName = import.meta.env.VITE_APP_NAME || 'Laravel';
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
setup({ el, App, props, plugin }) {
return createSSRApp({ render: () => h(App, props) })
.use(plugin)
.use(ZiggyVue)
.mount(el);
},
progress: {
color: '#4B5563',
},
});
I've tried changing the uri of the route from Route::get('login', [AuthenticatedSessionController::class, 'create']) ->name('login');
to Route::get('/login', [AuthenticatedSessionController::class, 'create']) ->name('login');
It doesn't make a difference.
This issue is problematic for me because search engines are following these bad routes.
Does anyone have any suggestions?
Upvotes: 0
Views: 1071
Reputation: 586
In laravel v11+ change make sure you use use Tighten\Ziggy\Ziggy;
instead of use Tightenco\Ziggy\Ziggy;
used in older versions
and in your return
return [
...parent::share($request),
'auth' => [
'user' => $request->user()
],
'ziggy' => function () use ($request) {
return array_merge((new Ziggy)->toArray(), [
'location' => $request->url(),
'query' => $request->query()
]);
},
];
which returns an object
{
"url": "http://your-app-url:8080",
"port": 8080,
"defaults": [],
"routes": {
"pulse": {
"uri": "pulse",
"methods": [
"GET",
"HEAD"
]
},
...
},
"location": "http://your-app-url:8080/profile",
"query": {
"tab": "profile-edit"
}
}
then you can access it in javascript qhen you visit this url http://your-app-url:8080/profile?tab=profile-edit
If you're using inertiajs you can visit your link with query passed
import { router } from '@inertiajs/react'
const goToProfileEditTab = () => {
router.visit(route('profile.edit', [{ tab: 'profile-edit' }]))
}
...
<button onClick={() => goToProfileEditTab()}>goToProfileEditTab</button>
const tab = props.ziggy.query.tab
console.log(tab)
// profile-edit
Upvotes: 0