If you're using Vue/Alpine or any other JavaScript in your Laravel projects, chances are at some point you'll need to grab authenticated user information.
Take this snippet as an example.
<template>
<img :src="$user.avatar" class="w-12 h-12 rounded-full mr-3">
</template>
That's just a Vue component, registered in Laravel, that needs to access the currently authenticated user's avatar (perhaps for a <new-comment />
component).
Getting straight into it, the easiest way to do this is to head to your base template (usually app.blade.php
) and add the following in the head
of the template.
<script>
window.User = {
id: {{ optional(auth()->user())->id }},
avatar: '{{ optional(auth()->user())->avatar() }}',
}
</script>
That gives us the id
and avatar
of the user, if they're available. The optional
helper in Laravel wraps both, returning null
if the user isn't authenticated.
If you have an example like the Vue template below, you'll be unable to access window
values from inside your template
.
<template>
<!-- This wont work -->
<img :src="window.User.avatar" class="w-12 h-12 rounded-full mr-3">
</template>
There are two ways to get around this.
In app.js
, the following snippet can be used to add $user
(or whatever you'd like it to be called) to Vue.
Vue.prototype.$user = window.User
Then you can access it like we did earlier.
<img :src="$user.avatar" class="w-12 h-12 rounded-full mr-3">
The great thing about this solution is that now, anywhere inside a Vue component (the mounted hook, for example), you can access this.$user.avatar
, etc.
In the script
section of your Vue component, you may wish to add this as a data property that directly pulls from the global User
object.
data () {
return {
user: window.User
}
}
Hint: You can omit window.
here, but I always add it for clarity.
The same principals apply here. I haven't worked with React much, but as long as you know how to globally share data with your favourite framework, you're good to go. It's a global object, so your options are pretty open.
Alpine is simple in terms of how it's pulled into a project, and usually you'll just have the script pulled in at the top of your page. That means, in your Alpine components, you'd just need to reference the global User
object.
<div x-data="{ user: window.User }">
<span x-text="user.id"></span>
</div>
The same goes for any methods you're invoking in Alpine. Just access window.User
or User
.
If you just have a few properties you want to access from the user, there's a super simple way to do this in one line, with the added ability to quickly pull in additional properties.
Take a look.
<script>
window.User = {!! json_encode(optional(auth()->user())->only('id', 'email')) !!}
</script>
If a user isn't authenticated, this gives you window.User = null
. If a user is signed in, you'll get an object with the properties you pass through to the only
method. This does mean you'll have to check that window.User
is not null
before you try to access any properties.
Just be aware, this unescapes the data that you're rendering to the page, potentially leading to XSS attacks. This simplified version works best for data that's heavily validated before being stored, or data that can't be stored as anything other than a safe value (e.g. the ID of the user).
It's a simple solution, but I've seen this method of accessing user data via JavaScript on some pretty big, popular sites. Next time you're curious, view the page source of a site you know to be using a mix of Laravel and JavaScript, you'll probably find this being used ✌️