> ## Documentation Index
> Fetch the complete documentation index at: https://artifactuse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Vue

> Use Artifactuse with Vue 3 and Nuxt 3

## Installation

```bash theme={null}
npm install artifactuse
```

## Setup

Initialize Artifactuse with `provideArtifactuse`:

```vue theme={null}
<script setup>
import { provideArtifactuse } from 'artifactuse/vue'
import 'artifactuse/styles'

provideArtifactuse({
  theme: 'dark',
  // branding: true, // Set to false to hide "Powered by Artifactuse" (requires license)
})
</script>
```

## Syntax Highlighting (Optional)

For code syntax highlighting, add Prism.js:

```bash theme={null}
npm install prismjs
```

```vue theme={null}
<script setup>
import Prism from 'prismjs'
import 'prismjs/components/prism-javascript'
import 'prismjs/components/prism-typescript'
import 'prismjs/components/prism-python'
import 'prismjs/themes/prism-tomorrow.css' // or any theme

import { provideArtifactuse } from 'artifactuse/vue'
import 'artifactuse/styles'

provideArtifactuse({ theme: 'dark' })
</script>
```

## Components

<CardGroup cols={3}>
  <Card title="ArtifactuseAgentMessage" icon="message-square" href="/docs/components/agent-message">
    Render AI messages with artifact detection
  </Card>

  <Card title="ArtifactusePanel" icon="panel-right" href="/docs/components/panel">
    Side panel for previews and code
  </Card>

  <Card title="ArtifactusePanelToggle" icon="toggle-right" href="/docs/components/panel-toggle">
    Toggle button with badge
  </Card>
</CardGroup>

### Quick Reference

```vue theme={null}
<template>
  <ArtifactuseAgentMessage 
    :content="message.content"
    :message-id="message.id"
    :typing="isStreaming"
    @form-submit="onFormSubmit"
    @social-copy="onSocialCopy"
    @media-open="onMediaOpen"
  />

  <ArtifactusePanel
    @ai-request="handleAIRequest"
    @save="handleSave"
    @export="handleExport"
    :external-preview="true"
  />

  <ArtifactusePanelToggle />
</template>

<script setup>
import { 
  ArtifactuseAgentMessage, 
  ArtifactusePanel, 
  ArtifactusePanelToggle 
} from 'artifactuse/vue'
</script>
```

## Composables

### useArtifactuse

Access Artifactuse state and methods:

```vue theme={null}
<script setup>
import { useArtifactuse } from 'artifactuse/vue'

const {
  // State (reactive)
  state,
  activeArtifact,
  artifactCount,
  hasArtifacts,
  
  // Methods
  processMessage,
  openArtifact,
  openPanel,
  closePanel,
  togglePanel,
  toggleFullscreen,
  setViewMode,      // 'preview' | 'code' | 'split' | 'edit'
  getPanelUrl,
  getTheme,
  setTheme,

  // Programmatic API
  openFile,          // Open file in panel (auto-detect language)
  openCode,          // Open code in panel (explicit language)
  updateFile,        // Update existing artifact in place
  clearArtifacts,    // Clear all artifacts

  // Events
  on,
  off,
} = useArtifactuse()
</script>

<template>
  <button @click="togglePanel">
    Artifacts ({{ artifactCount }})
  </button>
</template>
```

## Events

```vue theme={null}
<script setup>
import { useArtifactuse } from 'artifactuse/vue'
import { onMounted, onUnmounted } from 'vue'

const { on } = useArtifactuse()

onMounted(() => {
  on('ai:request', async ({ prompt, context }) => {
    const response = await yourAI.chat(prompt)
  })
  
  on('form:submit', ({ formId, values }) => {
    console.log('Form submitted:', values)
  })
  
  on('social:copy', ({ platform, text }) => {
    console.log('Copied:', platform, text)
  })
  
  on('media:open', ({ type, src }) => {
    console.log('Media opened:', type, src)
  })

  on('edit:save', ({ artifactId, artifact, code }) => {
    console.log('Code saved:', code)
  })

  // Panel lifecycle events
  on('panel:opened', () => {
    console.log('Panel opened')
  })

  on('panel:closed', () => {
    console.log('Panel closed')
  })

  on('panel:toggled', ({ isOpen }) => {
    console.log('Panel toggled:', isOpen)
  })
})
</script>
```

## Vue 2

For Vue 2 projects, import from `artifactuse/vue2`:

```vue theme={null}
<template>
  <div class="app-container">
    <div class="chat">
      <ArtifactuseAgentMessage 
        v-for="msg in messages" 
        :key="msg.id"
        :content="msg.content"
        :message-id="msg.id"
        :typing="msg.isStreaming"
        @form-submit="handleFormSubmit"
        @social-copy="handleSocialCopy"
        @media-open="handleMediaOpen"
      />
      
      <ArtifactusePanelToggle />
    </div>
    
    <ArtifactusePanel @ai-request="handleAIRequest" />
    
    <!-- Required: Portal target for fullscreen/mobile -->
    <portal-target name="artifactuse" />
  </div>
</template>

<script>
import { 
  ArtifactuseAgentMessage,
  ArtifactusePanel,
  ArtifactusePanelToggle,
  provideArtifactuse 
} from 'artifactuse/vue2'
import 'artifactuse/styles'

export default {
  components: {
    ArtifactuseAgentMessage,
    ArtifactusePanel,
    ArtifactusePanelToggle
  },
  setup() {
    provideArtifactuse({ 
      theme: 'dark',
      // branding: true, // Set to false to hide branding (requires license)
    })
    
    // ... your setup code
  }
}
</script>

<style>
html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
}

#app {
  height: 100%;
}

.app-container {
  display: flex;
  height: 100%;
  overflow: hidden;
}

.chat {
  flex: 1;
  padding: 20px;
  min-width: 0;
  overflow-y: auto;
}
</style>
```

### Vue 2.6 + @vue/composition-api

If you're using Vue 2.6 with `@vue/composition-api` or `@nuxtjs/composition-api`, add this alias to your build config:

<Tabs>
  <Tab title="Nuxt 2">
    ```js theme={null}
    // nuxt.config.js
    export default {
      build: {
        extend(config) {
          config.resolve.alias['vue'] = '@vue/composition-api';
        }
      }
    }
    ```
  </Tab>

  <Tab title="Webpack">
    ```js theme={null}
    // webpack.config.js
    module.exports = {
      resolve: {
        alias: {
          'vue': '@vue/composition-api'
        }
      }
    }
    ```
  </Tab>

  <Tab title="Vue CLI">
    ```js theme={null}
    // vue.config.js
    module.exports = {
      configureWebpack: {
        resolve: {
          alias: {
            'vue': '@vue/composition-api'
          }
        }
      }
    }
    ```
  </Tab>
</Tabs>

<Note>
  Vue 2.7+ has the Composition API built-in and works without any alias configuration.
</Note>

## Full Example

```vue theme={null}
<template>
  <div class="app-container">
    <div class="chat">
      <ArtifactuseAgentMessage 
        v-for="msg in messages" 
        :key="msg.id"
        :content="msg.content"
        :message-id="msg.id"
        :typing="msg.isStreaming"
        @form-submit="handleFormSubmit"
        @social-copy="handleSocialCopy"
        @media-open="handleMediaOpen"
      />
      
      <ArtifactusePanelToggle />
    </div>
    
    <ArtifactusePanel @ai-request="handleAIRequest" />
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { 
  ArtifactuseAgentMessage, 
  ArtifactusePanel, 
  ArtifactusePanelToggle,
  provideArtifactuse
} from 'artifactuse/vue'
import 'artifactuse/styles'

// Optional: Prism.js for syntax highlighting
import Prism from 'prismjs'
import 'prismjs/components/prism-javascript'
import 'prismjs/themes/prism-tomorrow.css'

provideArtifactuse({
  theme: 'dark',
  // branding: true, // Set to false to hide branding (requires license)
})

const messages = ref([])

function handleFormSubmit({ formId, values }) {
  // Send form data back to AI
  sendMessage(`Form submitted: ${JSON.stringify(values)}`)
}

function handleSocialCopy({ platform, text }) {
  console.log('Copied:', platform, text)
}

function handleMediaOpen({ type, src }) {
  console.log('Media opened:', type, src)
}

async function handleAIRequest({ prompt, context }) {
  const response = await yourAI.chat(prompt)
}
</script>

<style>
html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
}

#app {
  height: 100%;
}

.app-container {
  display: flex;
  height: 100%;
  overflow: hidden;
}

.chat {
  flex: 1;
  padding: 20px;
  min-width: 0;
  overflow-y: auto;
}
</style>
```
