tighten / ziggy

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

Conditional Routes / Filtering Routes / Requires Page Reload? #436

Closed broadstreetboy closed 3 years ago

broadstreetboy commented 3 years ago

Description

In a Laravel blade file, we conditionally load our routes. See below for the Ziggy call and context.

Why? Well, if the user is not authenticated we only want them to have access to the authentication routes and not be able to view the page source and see all routes. This works as expected with our VueJS/InertiaJS application, however, once the user authenticates the user can't access the new routes they should now have access to without refreshing the page. This refresh then updates the route list with the new routes they have access to.

@if(auth()->user())
   @routes
@else
   @routes('guest')
@endif

For what it's worth, the example above is illustratory only. We have multiple user types/groups.

Is there a better way to implement Ziggy to avoid the page reload while better protecting routes?

Thank you in advance!

bakerkretzmar commented 3 years ago

Hey, yeah in this case you're probably better off not using the @routes Blade directive and instead passing the routes along with the Inertia response. Try including it in your Inertia shared data:

use Tightenco\Ziggy\Ziggy;

class HandleInertiaRequests extends Middleware
{
    public function share(Request $request)
    {
        return array_merge(parent::share($request), [
            'ziggy' => fn () => (new Ziggy($request->user() ? null : 'guest'))->toArray(),
        ]);
    }
}

You may also need to set up a custom Vue mixin to make sure that your JS route() function is always using the latest Ziggy config from Inertia.

Does that make sense? Let me know if you get that working, if you're stuck I can try to set up a demo of how this could work (I didn't test the code above I'm just thinking out loud 😅).

Also, you'll definitely want to cache the generated routes, probably per-group, because generating them can be expensive. With @routes you get this for free since the entire output is dumped into the view, which is then cached.