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

gvisbeen's avatar

Inertia Layout slot and Vue 3 composition api emit event

I have a vue 3 layout for inertia, inside this layout there is the slot in which inertia places the "vue" page. I am using the <script setup> declaration. Normally props go down and emits go up. For some reason I can't get the emit event through to the parent. I want to pass a title up to the parent to be displayed in the nav menu. I've googled my head of, but can't seem to find a working solution. Help....

...parent
<html>
....
<slot @customevent="setTitle"></slot>
....
</html>

...dashboard.vue
<template>
  <Head>
    <title :title="__('dashboard.title')" />
    >
  </Head>
  <div class="flex flex-wrap max-w-3xl md:mx-auto justify-evenly">
   ....
   </div>
...
</template>
<script setup>
import { onMounted } from 'vue'
const emit = defineEmits(['customevent'])
onMounted(() => {
  emit('customevent')
  console.log('emit event')
})
</script>
0 likes
5 replies
wingly's avatar

As far as I know you cannot listen to events on slot. Scoped slots are used usually for cases like this.

1 like
gvisbeen's avatar

@wingly Thanx for your answer. I've tried finding an example using the vue 3 composition api, but couldn't find anything usefull, naming the slot resulted in the slot not being rendered at all. If you have an example you can point me to, that would be really helpful. For now I've fallen back on an eventbus using mitt.

gvisbeen's avatar

Forgot to answer back, but I went back to the options api with scoped slots and everything worked flawlessly.

1 like
devuser's avatar

@gvisbeen any chance you can explain how you made this worked? I am trying to do the same I have an AuthLayout.vue that acts as the parent and every single view just displays on the slot but I can't find a way to pass an event to my AuthLayout.vue so I can decrease a badge once an action happen I one of my pages!

Thanks in advance1

pkabore's avatar

Hi @gvisbeen!

In composition API mode, you can have persistent layouts achieved by setting conditionnaly the default layout in app.js

import Layout from './Layout'

createInertiaApp({
  resolve: name => {
    const page = require(`./Pages/${name}`).default
    if (page.layout === undefined && !name.startsWith('Public/')) {
      page.layout = Layout
    }
    return page
  },
  // ...
})

https://inertiajs.com/pages#creating-layouts

Please or to participate in this conversation.