tighten / ziggy

Use your Laravel routes in JavaScript.
MIT License
3.86k stars 247 forks source link

`route().current()` returns `undefined` for cyrillic letters inside URI #665

Closed anafro closed 11 months ago

anafro commented 1 year ago

Ziggy version

v1.6.2

Laravel version

v10.20.0

Description

route().current() doesn't work when url is cyrillic.

E.g.:

// web.php
Route::get('/магазин', function () {
    return Inertia::render('Store');
})->middleware(['auth', 'verified'])->name('store');

// SomeComponent.vue, when '/магазин' is opened
`route().current() === undefined // true, but false expected`

but

// web.php
Route::get('/train', function () {
    return Inertia::render('Dashboard');
})->middleware(['auth', 'verified'])->name('dashboard');

// SomeComponent.vue, when '/train' is opened
`route().current() === 'dashboard' // true`

route().current() also returns the same results when invoked right inside Chrome's console.

Ziggy call and context

// example.com/магазин  (магазин means 'store' in Russian)
// Displayed inside one of the Vue components
{{ route().current() }} 

// expected: 'store'
// returned: undefined

// (function route().current is defined)

Ziggy configuration

{
    "url": "http://127.0.0.1:8000",
    "port": 8000,
    "defaults": {},
    "routes": {
        "landing": {
            "uri": "/",
            "methods": [
                "GET",
                "HEAD"
            ]
        },
        "dashboard": {
            "uri": "train",
            "methods": [
                "GET",
                "HEAD"
            ]
        },
        "store": {
            "uri": "магазин",
            "methods": [
                "GET",
                "HEAD"
            ]
        },
        "statistics": {
            "uri": "статистика",
            "methods": [
                "GET",
                "HEAD"
            ]
        },
        "me": {
            "uri": "я",
            "methods": [
                "GET",
                "HEAD"
            ]
        },
        "notifications": {
            "uri": "уведомления",
            "methods": [
                "GET",
                "HEAD"
            ]
        },
    }
}

Route definition

Route::get('/', function () {
    return Inertia::render('Landing', [
        'canLogin' => Route::has('login'),
        'canRegister' => Route::has('register'),
    ]);
})->middleware(['only-guests'])->name('landing');

Route::get('/train', function () {
    return Inertia::render('Dashboard');
})->middleware(['auth', 'verified'])->name('dashboard');

Route::get('/магазин', function () {
    return Inertia::render('Store');
})->middleware(['auth', 'verified'])->name('store');

Route::get('/статистика', function () {
    return Inertia::render('Statistics');
})->middleware(['auth', 'verified'])->name('statistics');

Route::get('/я', function () {
    return Inertia::render('Profile');
})->middleware(['auth', 'verified'])->name('me');

Route::get('/уведомления', function () {
    return Inertia::render('Notifications');
})->middleware(['auth', 'verified'])->name('notifications');

Route::get('/выход', function () {
    return Inertia::render('Logout');
})->middleware(['auth', 'verified'])->name('logout');

Route::middleware('auth')->group(function () {
    Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
    Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
    Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
});
anafro commented 1 year ago

I added a test into Ziggy that tests this, and it passes, but I found something:

When there are cyrillic letters in URI opened in browser, window.location.href returns not http://localhost:8000/магазин, for example, but http://localhost:8000/%D0%BC%D0%B0%D0%B3%D0%B0%D0%B7%D0%B8%D0%BD.

I think Ziggy should decode %XX codes into actual URI or encode route URI-s into %XX codes

anafro commented 1 year ago

Temporary solution for checking if the route is current:

// Now we are at example.com/магазин

const checkingRoute = 'store';
const isCurrent = window.location.href.endsWith(encodeURI(route(checkingRoute)));  // true