Skip to main content
Vuetify0 v1.0 is here
Vuetify0 Logo
Theme
Mode
Palettes
Accessibility
Vuetify One
Sign in to Vuetify One

Access premium tools across the Vuetify ecosystem — Bin, Play, Studio, and more.

Not a subscriber? See what's included

createContext

Type-safe dependency injection factory built on Vue’s provide/inject. Shares state across component trees without prop drilling.

Edit this page
Report a Bug
Open issues
View on GitHub
Copy Markdown

StableAdvancedJun 29, 2026

Usage

createContext has two modes depending on whether you pass a key:

Static Key Mode

For singletons — one instance for the entire app (theme, locale, breakpoints):

ts
import { shallowRef } from 'vue'
import { createContext } from '@vuetify/v0'
import type { ShallowRef } from 'vue'

interface MyContext {
  isDisabled: ShallowRef<boolean>
  isSelected?: ShallowRef<boolean>
  type: 'primary' | 'secondary' | 'tertiary'
}

const [useContext, provideContext] = createContext<MyContext>('namespace')

provideContext({
  isDisabled: shallowRef(false),
  isSelected: shallowRef(true),
  type: 'primary',
})

export { useContext }

Dynamic Key Mode

For multiple independent instances of the same context type (nested panels, tabs within tabs). Omit the key — both provide and use accept a runtime key at call time:

ts
interface PanelContext {
  isOpen: ShallowRef<boolean>
  toggle: () => void
}

const [usePanel, providePanel] = createContext<PanelContext>()

// Provider — runtime key identifies this instance
providePanel('panel-main', mainContext)
providePanel('panel-sidebar', sidebarContext)

// Consumer — same runtime key to inject
const panel = usePanel('panel-main')

Default Values

By default, useContext throws if the context isn’t found. Pass a defaultValue to make injection optional — useful for components that work with or without a parent:

ts
// Static key — default passed at creation time
const [usePanel, providePanel] = createContext<PanelContext>('v0:panel', fallbackContext)
const panel = usePanel() // returns fallbackContext if not provided

// Dynamic key — default passed at call time
const [usePanel, providePanel] = createContext<PanelContext>()
const panel = usePanel('v0:panel', fallbackContext)

Suffix Pattern

For parent-child context hierarchies where a child needs to know which parent it belongs to:

ts
// Item context appends ':item' to whatever parent key it's given
const [useItem, provideItem] = createContext<ItemContext>({ suffix: 'item' })

provideItem('v0:panel', itemContext)  // Provides to 'v0:panel:item'
const item = useItem('v0:panel')      // Injects from 'v0:panel:item'

Architecture

createContext is the foundation for all dependency injection in Vuetify0:

Context Hierarchy

Use controls to zoom and pan. Click outside or press Escape to close.

Context Hierarchy

Examples

Notification System

A four-file notification system that shows the canonical createContext provider/consumer split. context.ts is the only file that calls createContext — it defines the NotificationContext interface (a ShallowReactive<Notification[]> array plus notify, dismiss, and clear methods) and exports the [useNotifications, provideNotifications] tuple. NotificationProvider.vue creates the reactive state and method implementations, passes the assembled object to provideNotifications(), then renders only a slot — it is an invisible wrapper with no visual output. NotificationConsumer.vue destructures all four members from useNotifications() and drives a color-coded notification list: four buttons fire random(type) which picks a message at random and calls notify(); clicking a notification card calls dismiss(id) to splice it out; “Clear” calls clear() to empty the array. notifications.vue composes the two components.

The key architectural choice is that NotificationConsumer imports exclusively from context.ts, never from the provider. This means the consumer is reusable: drop it inside any provider that satisfies the NotificationContext interface and it works without modification — the same contract that makes testing straightforward, since a test can provideNotifications() a stub context without mounting the full provider tree.

shallowReactive is used for the notifications array (not ref) because the array is mutated in place via push and splice — Vue’s reactivity tracks those mutations without needing to replace the reference. For contexts that wrap composables from the selection or registry layer instead of raw reactive state, the same file-separation pattern applies.

Provider/Consumer Data Flow

Use controls to zoom and pan. Click outside or press Escape to close.

Provider/Consumer Data Flow

File breakdown:

FileRole
context.tsDefines the NotificationContext interface and creates the typed [useNotifications, provideNotifications] tuple
NotificationProvider.vueImplements the context—creates reactive state and methods, then calls provideNotifications()
NotificationConsumer.vueConsumes the context via useNotifications() to display and interact with notifications
notifications.vueEntry point that composes Provider around Consumer

Key patterns:

  • Provider components are invisible wrappers that render only <slot />

  • Consumers import only from context.ts, never from the Provider

  • shallowReactive for arrays that mutate in place

Click the buttons to add notifications. Click a notification to dismiss it.

No notifications. Click a button above to add one.

FAQ

Discord
Need help? Join our community for support and discussions ↗

API Reference

The following API details are for the createContext composable.
Was this page helpful?

© 2016-1970 Vuetify, LLC
Services
Ctrl+/