> ## Documentation Index
> Fetch the complete documentation index at: https://mcp-b-sync-npm-packages-docs-bf03420.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Nuxt Integration

> Integrate WebMCP tools with Nuxt 3, handling SSR safely.

<Card title="Community Example" icon="github" href="https://github.com/mikechao/nuxt3-mcp-b-demo">
  Full-stack Nuxt 3 with SSR support by Mike Chao
</Card>

Nuxt's SSR requires ensuring WebMCP code only runs on the client.

## Client-Only Plugin

Create a plugin that initializes WebMCP on the client:

```typescript "plugins/webmcp.client.ts" theme={null}
import '@mcp-b/global';

export default defineNuxtPlugin(() => {
  // .client.ts suffix ensures this only runs in browser
});
```

## Basic Usage

Use `import.meta.client` to guard registration:

```vue theme={null}
<script setup lang="ts">
import { onMounted, onUnmounted } from 'vue';

let reg: { unregister: () => void } | null = null;

if (import.meta.client) {
  onMounted(() => {
    reg = navigator.modelContext.registerTool({
      name: 'get_page',
      description: 'Get current page info',
      inputSchema: { type: 'object', properties: {} },
      async execute() {
        return { content: [{ type: 'text', text: window.location.pathname }] };
      }
    });
  });

  onUnmounted(() => reg?.unregister());
}
</script>
```

## With Server Data

```vue "pages/products/[id].vue" theme={null}
<script setup lang="ts">
const route = useRoute();
const { data: product } = await useFetch(`/api/products/${route.params.id}`);

let reg: { unregister: () => void } | null = null;

if (import.meta.client) {
  onMounted(() => {
    reg = navigator.modelContext.registerTool({
      name: 'get_product',
      description: 'Get current product details',
      inputSchema: { type: 'object', properties: {} },
      async execute() {
        if (!product.value) return { content: [{ type: 'text', text: 'No product' }] };
        return { content: [{ type: 'text', text: JSON.stringify(product.value) }] };
      }
    });
  });

  onUnmounted(() => reg?.unregister());
}
</script>
```

## ClientOnly Wrapper

For client-only components:

```vue "app.vue" theme={null}
<template>
  <ClientOnly>
    <ToolRegistrationComponent />
  </ClientOnly>
  <NuxtPage />
</template>
```

## Common Gotchas

<AccordionGroup>
  <Accordion title="'navigator is not defined' error">
    Code is running during SSR. Use one of:

    * `import.meta.client` check
    * `.client.ts` suffix for plugins
    * `<ClientOnly>` component
    * `onMounted` hook (runs client-side only)
  </Accordion>

  <Accordion title="Tools disappear after navigation">
    Register tools in `app.vue` or a layout so they persist across routes.
  </Accordion>
</AccordionGroup>

## Development

Use [Chrome DevTools MCP](/packages/chrome-devtools-mcp) for AI-driven development - your AI can write, discover, and test tools in real-time.
