Layout and Pages

Hi guys, I'm trying to have a pages/index.vue that route to components/HomePage.vue when connected and components/LandingPage.vue when non connected And i also have layouts/default.vue for all pages when connected who contains a menu, and layouts/unauthenticated.vue for the LandingPage.vue only for now:
<script setup>
import { useUserStore } from '@/stores/user'
import HomePage from '@/components/HomePage.vue'
import LandingPage from '@/components/LandingPage.vue'

const userStore = useUserStore()
const { isAuthenticated } = storeToRefs(userStore)

definePageMeta({
layout: isAuthenticated.value ? 'default' : 'unauthenticated'
})
</script>

<template>
<div>
<!-- Conditionally render the components based on authentication state -->
<component :is="isAuthenticated ? HomePage : LandingPage" />
</div>
</template>
<script setup>
import { useUserStore } from '@/stores/user'
import HomePage from '@/components/HomePage.vue'
import LandingPage from '@/components/LandingPage.vue'

const userStore = useUserStore()
const { isAuthenticated } = storeToRefs(userStore)

definePageMeta({
layout: isAuthenticated.value ? 'default' : 'unauthenticated'
})
</script>

<template>
<div>
<!-- Conditionally render the components based on authentication state -->
<component :is="isAuthenticated ? HomePage : LandingPage" />
</div>
</template>
` SO i have this code but the part : definePageMeta({ layout: isAuthenticated.value ? 'default' : 'unauthenticated' }) Is causing me an error : index.vue?macro=true:2 Uncaught ReferenceError: isAuthenticated is not defined at index.vue?macro=true:2:11  Anyone has an idea ?
3 Replies
kapa.ai
kapa.ai2mo ago
Hi @BobLamarley. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- The error you're encountering is because definePageMeta is evaluated at build time, not at runtime. This means you can't use reactive values or runtime logic inside it. Let me explain how you can achieve what you're trying to do based on the Nuxt documentation. To dynamically change layouts based on authentication state, you have a couple of options: 1. Use setPageLayout in a middleware or plugin: You can create a middleware that checks the authentication state and sets the layout accordingly:
// middleware/auth.js
export default defineNuxtRouteMiddleware((to, from) => {
const userStore = useUserStore()
const { isAuthenticated } = storeToRefs(userStore)

if (isAuthenticated.value) {
setPageLayout('default')
} else {
setPageLayout('unauthenticated')
}
})
// middleware/auth.js
export default defineNuxtRouteMiddleware((to, from) => {
const userStore = useUserStore()
const { isAuthenticated } = storeToRefs(userStore)

if (isAuthenticated.value) {
setPageLayout('default')
} else {
setPageLayout('unauthenticated')
}
})
Then, in your pages/index.vue, you can use this middleware:
<script setup>
definePageMeta({
middleware: ['auth']
})
</script>
<script setup>
definePageMeta({
middleware: ['auth']
})
</script>
2. Use <NuxtLayout> component in your page: Alternatively, you can handle the layout change directly in your page component:
<script setup>
import { useUserStore } from '@/stores/user'
import HomePage from '@/components/HomePage.vue'
import LandingPage from '@/components/LandingPage.vue'

const userStore = useUserStore()
const { isAuthenticated } = storeToRefs(userStore)
</script>

<template>
<NuxtLayout :name="isAuthenticated ? 'default' : 'unauthenticated'">
<component :is="isAuthenticated ? HomePage : LandingPage" />
</NuxtLayout>
</template>
<script setup>
import { useUserStore } from '@/stores/user'
import HomePage from '@/components/HomePage.vue'
import LandingPage from '@/components/LandingPage.vue'

const userStore = useUserStore()
const { isAuthenticated } = storeToRefs(userStore)
</script>

<template>
<NuxtLayout :name="isAuthenticated ? 'default' : 'unauthenticated'">
<component :is="isAuthenticated ? HomePage : LandingPage" />
</NuxtLayout>
</template>
This approach allows you to dynamically change the layout based on the authentication state at runtime. For more information on layouts and how to use them dynamically, you can refer to the Nuxt Layouts documentation. Remember, the definePageMeta function is meant for static metadata that's known at build time. For dynamic values that change at runtime, you need to use one of the approaches mentioned above. Source Source ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@314138038995255298> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Omnislash
Omnislash2mo ago
Depending on how much the layout changes, I wouldn't bother much and do the same thing as you did in your page. Like, displaying a different menu depending on isAuthenticated

Did you find this page helpful?