Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

nyce's avatar

Inertia usePage() not working in Vue3 composition API

Here's some documentation on how to use usePage() in Composition API with inertia >>.

Except of course, that it doesn't work, and I'm trying to get to the bottom of why.

The code in my component is as follows:

<script setup>
import { ref, computed }       from 'vue';
import { usePage, useForm }    from '@inertiajs/vue3';         // doesn't work
import { usePage as usePage2 } from '@inertiajs/inertia-vue3'; // deprecated, but works(ish)

const page = usePage();
const authenticated1 = computed(() => page.props.auth.authenticated); // This bugs out, saying page.props is undefined
console.log('page', page, page.props, page.value); // Logs: 'page' Object undefined undefined
const page2 = ref(usePage2());
console.log ('page2', page2, page2.value.props.auth.authenticated);  // This prints "false" into the console, which is what I want!

//... blah...
</script>

Can anyone help me understand:

  1. Why I need to wrap my call to usePage2() in a ref() when the documentation says nothing of the sort? Removing the ref() means that I can no longer access my props.
  2. Why usePage() doesn't work, even though it's the documented solution? As an aside, wrapping it in a ref() doesn't fix the issue in the same way that it does for usePage2()

Aside: the props are being passed in from App\Http\Middleware\HandleInertiaRequests::share() and appears to work correctly as far as I can tell. I just include this FYI to fend off "have you checked this" type questions. The fact that usePage2() can access the prop suggests to me that there's no problem passing in the prop from the PHP side.

public function share (Request $request) : array {
    return array_merge (parent::share($request), [
        'auth' => [
            'authenticated' => Illuminate\Support\Facade\Auth::check(),
        ],
    ]);
}

If there are any typos, they aren't a part of the problem; it's because I've hacked out some code from the real component for illustration purposes

0 likes
4 replies
LaryAI's avatar

Certainly! Let’s break down what’s happening and how to resolve it.

1. Why does usePage() from @inertiajs/vue3 not work as expected in Vue 3 Composition API?

The Problem

When you use:

import { usePage } from '@inertiajs/vue3';

const page = usePage();
console.log(page, page.props); // page.props is undefined

You’re seeing page.props as undefined. That’s because, in Vue 3 with Inertia’s new package (@inertiajs/vue3), usePage() returns a Vue ref (a reactive reference), not a plain object.

So, to access the actual page object, you need to use .value:

const page = usePage();
console.log(page.value.props); // This should work

Correct Usage

If you want to access props reactively, you should do:

const page = usePage();

const authenticated = computed(() => page.value.props.auth.authenticated);

2. Why does usePage2() from @inertiajs/inertia-vue3 work differently?

The old package (@inertiajs/inertia-vue3) returned the page object directly, not a ref. That’s why you could access page2.props directly. If you wrap it in a ref(), you get a double ref, which is not necessary.

3. Why does wrapping usePage() in ref() not help?

Because usePage() already returns a ref. Wrapping it in another ref() just gives you a ref to a ref, which is not what you want.


Summary Table

Package What usePage() returns How to access props
@inertiajs/inertia-vue3 Plain object page.props
@inertiajs/vue3 Vue ref page.value.props

How to Fix Your Code

Update your code to use .value with the new package:

<script setup>
import { computed } from 'vue';
import { usePage } from '@inertiajs/vue3';

const page = usePage();

const authenticated = computed(() => page.value.props.auth.authenticated);

console.log('page', page, page.value, page.value.props);
</script>

No need to wrap usePage() in ref()!


Extra: Why does the docs not mention this?

The Inertia docs for Vue 3 do mention that usePage() returns a ref. But it’s easy to miss if you’re used to the old API. Always remember: in Vue 3, most composables return refs for reactivity.


TL;DR

  • With @inertiajs/vue3, always use .value to access the actual page object returned by usePage().
  • Don’t wrap usePage() in ref().
  • Update your computed properties to use page.value.props.

Example:

const page = usePage();
const authenticated = computed(() => page.value.props.auth.authenticated);

That should resolve your issue!

nyce's avatar

@LaryAI This is the wrong answer. You can see from the code that I posted originally that the debug console.log(page.value, page.props) returns undefined undefined. In other words, even the reactivity doesn't work when calling usePage().

nyce's avatar

I should probably add that I've tried many combinations of usePage() and usePage2() along with adding .value to the assigned variables. Nothing appears to work. I've asked my own AI to help as well, but it also can't seem to resolve the problem.

nyce's avatar

Okay, I worked it out. The problem is that the page is defined in a different library than that from which the usePage() was being called.

In my app.js, I define the function createInertiaApp from the wrong library. In other words, this is wrong:

import { createInertiaApp, Link, Head } from '@inertiajs/inertia-vue3';

And this is right:

import { createInertiaApp, Link, Head } from '@inertiajs/vue3';

Now, in the component I can do:

import { usePage }         from '@inertiajs/vue3';
const page = usePage();
console.log('the page is', page.props.auth.authenticated);

No need for .value either after page or authenticated!!!

Please or to participate in this conversation.