{"record":{"id":"7aeb4a413d074f25","repo":"vuetifyjs/vuetify","slug":"vuetify-could-not-find-injected-layout","errorCode":null,"errorMessage":"[Vuetify] Could not find injected layout","messagePattern":"\\[Vuetify\\] Could not find injected layout","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vuetify/src/composables/layout.ts","lineNumber":93,"sourceCode":"  fullHeight: Boolean,\n}, 'layout')\n\n// Composables\nexport const makeLayoutItemProps = propsFactory({\n  name: {\n    type: String,\n  },\n  order: {\n    type: [Number, String],\n    default: 0,\n  },\n  absolute: Boolean,\n}, 'layout-item')\n\nexport function useLayout () {\n  const layout = inject(VuetifyLayoutKey)\n\n  if (!layout) throw new Error('[Vuetify] Could not find injected layout')\n\n  return {\n    getLayoutItem: layout.getLayoutItem,\n    mainRect: layout.mainRect,\n    mainStyles: layout.mainStyles,\n  }\n}\n\nexport function useLayoutItem (options: {\n  id: string | undefined\n  order: Ref<number>\n  position: Ref<Position>\n  layoutSize: Ref<number | string>\n  elementSize: Ref<number | string | undefined>\n  active: Ref<boolean>\n  disableTransitions?: Ref<boolean>\n  absolute: Ref<boolean | undefined>\n}) {","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/vuetifyjs/vuetify/blob/8d153908dffb7592eb389ddbfbab955a0ccc977f/packages/vuetify/src/composables/layout.ts#L75-L111","documentation":"useLayout() calls Vue's inject() for VuetifyLayoutKey. That key is only provided by createLayout(), which runs inside <v-app> and <v-layout>. The composable throws when no such ancestor exists in the component tree, because the layout registry (mainRect, getLayoutItem, mainStyles) it wants to read from was never set up.","triggerScenarios":"Calling useLayout() directly, or rendering a component that calls it (e.g. <v-main>, <v-app-bar>, <v-navigation-drawer>, <v-footer>, <v-system-bar>), in a subtree that is not nested under <v-app> or <v-layout>. Also fires in component unit tests mounted without <v-app>.","commonSituations":"Forgetting to wrap the application template in <v-app>; mounting a single Vuetify layout-item component in a test harness; SSR render where the root component omits <v-app>; refactoring that moved a layout item outside the v-app tree.","solutions":["Wrap the component subtree in <v-app> (it provides the layout itself) or in <v-layout>.","Confirm app.use(createVuetify()) ran and that <v-app> is the template root.","In tests, mount the component under <v-app>, or provide VuetifyLayoutKey via the test wrapper."],"exampleFix":"// before\n<VMain>Hello</VMain>\n\n// after\n<v-app>\n  <VMain>Hello</VMain>\n</v-app>","handlingStrategy":"type-guard","validationCode":"// Run inside setup() before relying on the layout.\nimport { inject } from 'vue'\nimport { VuetifyLayoutKey } from 'vuetify'\nconst layout = inject(VuetifyLayoutKey, null)\nif (!layout) {\n  // No <v-app>/<v-layout> ancestor: render a fallback, do not call layout APIs.\n  console.warn('Vuetify layout not provided')\n}","typeGuard":"import { inject } from 'vue'\nimport { VuetifyLayoutKey } from 'vuetify'\nexport function hasVuetifyLayout (): boolean {\n  return inject(VuetifyLayoutKey, null) != null\n}","tryCatchPattern":null,"preventionTips":["Always root Vuetify UI under <v-app>.","In tests, mount under <v-app> or provide VuetifyLayoutKey.","Never render layout-item components via teleport to nodes outside v-app."],"tags":["injection","layout","composition-api","vue"],"backgroundTag":null,"analyzedSha":"8d153908dffb7592eb389ddbfbab955a0ccc977f","analyzedAt":"2026-08-12T21:54:20.596Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}