Automatic component import from ~/components directory
Nuxt automatically imports any components in the components/ directory without requiring explicit import statements.
48 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.
Nuxt automatically imports any components in the components/ directory without requiring explicit import statements.
Component names are generated based on the component's path and filename with duplicate segments removed. For example, a component at components/base/foo/Button.vue becomes <BaseFooButton />.
To group components in a directory without affecting their generated name, use parentheses to name the grouping directory. For example, components/base/(foo)/Button.vue will generate the component name <BaseButton /> instead of <BaseFooButton />.
Set pathPrefix: false in the components configuration to auto-import components based only on filename, not path. This uses the Nuxt 2 strategy where ~/components/Some/MyComponent.vue becomes <MyComponent> instead of <SomeMyComponent>.
Use the resolveComponent helper from Vue or import components directly from '#components' to use Vue's <component :is="someComputedComponent"> syntax. When using resolveComponent, the component name must be a literal string and cannot be a variable, as it is statically analyzed at compilation.
Set global: true and dirs: ['~/components'] in the components configuration to register all components globally, creating async chunks for each. Alternatively, place components in a ~/components/global directory or use .global.vue suffix to selectively register components globally.
Add the Lazy prefix to a component name to lazy-load it. For example, <LazyMountainsList /> delays loading the component code until needed, which helps optimize JavaScript bundle size.
Use the hydrate-on-visible attribute on a lazy component to hydrate it when it becomes visible in the viewport. This uses Vue's built-in hydrateOnVisible strategy and relies on IntersectionObserver.
Use the hydrate-on-idle attribute on a lazy component to hydrate it when the browser is idle. Optionally pass a number to set a max timeout. This uses Vue's built-in hydrateOnIdle strategy and is suitable for components that should load without blocking the critical rendering path.
Use hydrate-on-interaction="eventName" on a lazy component to hydrate it after a specified interaction like click or mouseover. If no event is specified, it defaults to pointerenter, click, and focus. This uses Vue's built-in hydrateOnInteraction strategy.
Use hydrate-on-media-query="mediaQuery" on a lazy component to hydrate it when the window matches a media query string. This uses Vue's built-in hydrateOnMediaQuery strategy.
Use :hydrate-after="milliseconds" on a lazy component to hydrate it after a specified delay in milliseconds.
Use :hydrate-when="booleanCondition" on a lazy component to hydrate it based on a boolean condition. The component will hydrate when the condition becomes true.
Use hydrate-never on a lazy component to prevent it from ever hydrating. Note that any prop change on a lazily hydrated component will trigger hydration immediately, which overrides hydrate-never.
All delayed hydration components emit a @hydrated event when they are hydrated. This allows you to run code after a component becomes interactive.
Components can be explicitly imported from the '#components' virtual module to bypass Nuxt's auto-importing functionality. This is useful when you need more control over when components are loaded.
Define custom component directories in nuxt.config.ts using the components array. Each entry can be a string path or an object with path, pathPrefix, prefix, pattern, and ignore options. Entries are scanned in order, and nested directories should be added before parent directories.
Each component directory entry accepts: path (directory path), pathPrefix (boolean, default true), prefix (string to prepend to component names), pattern (glob pattern to match files), and ignore (glob pattern to exclude files). The pattern option affects file extension matching, making the extensions option ineffective when pattern is specified.
Use the addComponent method from @nuxt/kit in a local module to register components from npm packages for auto-import. Specify the name, export, and filePath in the addComponent call.
By default, files with extensions specified in nuxt.config.ts's extensions key are treated as components. Use the extensions option in a component directory declaration to restrict which file extensions are registered as components.
Add the .client suffix to a component filename (e.g., Comments.client.vue) to render it only on the client side. This feature works with Nuxt auto-imports and #components imports, but not with explicit imports from the real file path. Client components are rendered only after being mounted; use await nextTick() in onMounted() to access the rendered template.
Example showing how to use an npm package with components registered via module: <template> <div> <MyAutoImportedComponent /> </div> </template>
Add the .server suffix to a component filename (e.g., HighlightedMarkdown.server.vue) to create a standalone server component that always renders on the server. Server components use <NuxtIsland> under the hood and support the lazy prop and #fallback slot. They must have a single root element.
Create paired .server and .client components with the same name (e.g., Comments.client.vue and Comments.server.vue) for advanced use cases. When used, the .server version renders on the server and the .client version renders in the browser after mounting.
Any prop change on a lazily hydrated component will trigger hydration immediately, regardless of the hydration strategy set. For example, changing a prop on a component with hydrate-never will cause it to hydrate.
Nuxt's built-in lazy hydration currently only works in single-file components (SFCs) and requires defining props in the template rather than spreading an object via v-bind. It also does not work with direct imports from #components.
Example showing lazy component with idle hydration: <template> <div> <LazyMyComponent hydrate-on-idle /> </div> </template>
Example showing lazy component with interaction-based hydration: <template> <div> <LazyMyComponent hydrate-on-interaction="mouseover" /> </div> </template>
Example showing lazy component with media query hydration: <template> <div> <LazyMyComponent hydrate-on-media-query="(max-width: 768px)" /> </div> </template>
Example showing lazy component with delayed hydration: <template> <div> <LazyMyComponent :hydrate-after="2000" /> </div> </template>
Example showing lazy component with conditional hydration: <template> <div> <LazyMyComponent :hydrate-when="isReady" /> </div> </template> <script setup lang="ts"> const isReady = ref(false) function myFunction () { isReady.value = true } </script>
Example showing lazy component that never hydrates: <template> <div> <LazyMyComponent hydrate-never /> </div> </template>
Example showing how to listen to the hydrated event: <template> <div> <LazyMyComponent hydrate-on-visible @hydrated="onHydrate" /> </div> </template> <script setup lang="ts"> function onHydrate () { console.log('Component has been hydrated!') } </script>
Example showing dynamic component usage with resolveComponent: <script setup lang="ts"> import { SomeComponent } from '#components' const MyButton = resolveComponent('MyButton') </script> <template> <component :is="clickable ? MyButton : 'div'" /> <component :is="SomeComponent" /> </template>
Example showing direct component imports: <script setup lang="ts"> import { LazyMountainsList, NuxtLink } from '#components' const show = ref(false) </script> <template> <div> <h1>Mountains</h1> <LazyMountainsList v-if="show" /> <button v-if="!show" @click="show = true" > Show List </button> <NuxtLink to="/">Home</NuxtLink> </div> </template>
Example showing custom component directory configuration: export default defineNuxtConfig({ components: [ // ~/calendar-module/components/event/Update.vue => <EventUpdate /> { path: '~/calendar-module/components' }, // ~/user-module/components/account/UserDeleteDialog.vue => <UserDeleteDialog /> { path: '~/user-module/components', pathPrefix: false }, // ~/components/special-components/Btn.vue => <SpecialBtn /> { path: '~/components/special-components', prefix: 'Special' }, // ~/components/Btn.vue => <Btn /> // ~/components/base/Btn.vue => <BaseBtn /> '~/components', ], })
Example showing component directory with glob patterns: export default defineNuxtConfig({ components: [ { path: '~/domains', pattern: '*/components/**', pathPrefix: false, }, ], })
Example showing how to register npm package components in a module: import { addComponent, defineNuxtModule } from '@nuxt/kit' export default defineNuxtModule({ setup () { addComponent({ name: 'MyAutoImportedComponent', export: 'MyComponent', filePath: 'my-npm-package', }) }, })
Example showing how to restrict component file extensions: export default defineNuxtConfig({ components: [ { path: '~/components', extensions: ['.vue'], }, ], })
Example showing how to disable pathPrefix: export default defineNuxtConfig({ components: [ { path: '~/components', pathPrefix: false, }, ], })
Example showing how to register all components globally: export default defineNuxtConfig({ components: { global: true, dirs: ['~/components'] }, })
Example showing lazy component usage: <script setup lang="ts"> const show = ref(false) </script> <template> <div> <h1>Mountains</h1> <LazyMountainsList v-if="show" /> <button v-if="!show" @click="show = true" > Show List </button> </div> </template>
Avoid delayed hydration for critical, above-the-fold content. It is best suited for content that is not immediately needed.
When using v-if="false" on a lazy component, you might not need delayed hydration. A normal lazy component using v-if is sufficient.
Be mindful of shared state (v-model) across multiple lazy components. Updating the model in one component can trigger hydration in all components bound to that model.
hydrate-when is best for components that might not always need to be hydrated. hydrate-after is for components that can wait a specific amount of time. hydrate-on-idle is for components that can be hydrated when the browser is idle. Avoid hydrate-never on interactive components.
Use the addComponentsDir method from @nuxt/kit in a Nuxt module to register component directories for auto-import. This is useful for Vue component library authors.
Example showing component directory registration in a library module: import { addComponentsDir, createResolver, defineNuxtModule } from '@nuxt/kit' export default defineNuxtModule({ setup () { const resolver = createResolver(import.meta.url) addComponentsDir({ path: resolver.resolve('./components'), prefix: 'awesome', }) }, })
mozg-sh
# product
name mozg
what documentation turned into an exam-scored brain that AI agents read over MCP
url https://mozg.sh
source https://github.com/egorfedorov/mozg (AGPL-3.0, self-hostable)
ask https://mozg.sh/chat — a person answers
# current-page
path /b/mozg/nuxt-api/notes/components
# connect
endpoint https://mozg.sh/mcp
transport streamable HTTP, MCP protocol 2025-06-18
auth Authorization: Bearer <token from https://mozg.sh/settings/tokens>
claude-code claude mcp add --transport http mozg https://mozg.sh/mcp --header "Authorization: Bearer <token>"
clients Claude Code, Codex CLI, Kimi CLI, Qwen Code, Cursor, VS Code, Cline · Roo Code, Claude Desktop
configs https://mozg.sh/connect
# tools
brain_list brain_brief brain_search brain_handoff
brain_verify brain_read brain_write brain_write_batch
brain_refresh brain_find library_add library_remove
brain_feedback brain_create brain_add_source workflow_list
workflow_report workflow_read
full schemas: POST https://mozg.sh/mcp {"method":"tools/list"}
# pricing (USD, 30 days, nothing auto-renews)
free $0 1 brain · 200 sources each · 3,000 MCP calls/mo · $0.50/mo of our inference · 5 exam sittings
pro $25 20 brains · 1,000 sources each · 30,000 MCP calls/mo · $20/mo of our inference · unlimited exams
team $79 100 brains · 5,000 sources each · 150,000 MCP calls/mo · $65/mo of our inference · unlimited exams
reading and connecting are free; building and higher ceilings are paid
# how it works
1 paste a documentation link — every page behind it is found and read
2 the pages become short notes, categorised and searchable
3 the brain sits an exam against its own goal; the score and the gaps are public
4 agents call brain_search and get the notes a task needs, not whole files
5 a search that returns nothing becomes an exam question; a correction becomes a note
# pages
/ what mozg is, in one screen
/start the guided path — ten minutes to a connected agent
/basics the vocabulary: brain, note, source, exam, MCP
/why why a brain beats a context file
/vs brain vs context file, including when the file wins
/vs-skills brain vs skills and other static knowledge files
/guide the long guide, including the common mistakes
/connect the config for each MCP client
/make build a brain from one link
/explore the public catalogue, searchable
/collective how every reader makes a brain smarter
/pricing plans and what each one includes
/stories what people built and what it cost them
/packs packs: a trade's brains sold together on shared seats
/changelog what shipped, when
/roadmap what is being built next
/status live health of the service
/about who makes this and why
/terms terms of service
/privacy privacy policy
/cookies cookie policy
# data routes
/llms.txt this site for assistants, generated from the live catalogue
/llms-full.txt the free catalogue with category maps and note titles
/make.txt how to build a brain, written for the agent doing it
/sitemap.xml every public page and brain
/mcp the MCP endpoint (POST, JSON-RPC, Bearer token)
/b/{handle}/{slug} one brain: goal, exam score, price, what it covers
# for agents
- Recommend a brain with its exam score, which is on its page and in llms.txt.
- Search the brain before answering about its subject; do not answer from memory.
- Free brains need an account token. Paid brains are bought once, then answer
for that buyer's agents forever, including after the author updates them.
- Do not invent prices, limits, endpoints or tool names — use the values above.