> ## 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.

# React

> Use Artifactuse with React and Next.js

## Installation

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

## Setup

Wrap your app with `ArtifactuseProvider`:

```jsx theme={null}
import { ArtifactuseProvider } from 'artifactuse/react'
import 'artifactuse/styles'

function App() {
  return (
    <ArtifactuseProvider config={{ 
      theme: 'dark',
      // branding: true, // Set to false to hide "Powered by Artifactuse" (requires license)
    }}>
      <YourApp />
    </ArtifactuseProvider>
  )
}
```

## Syntax Highlighting (Optional)

For code syntax highlighting, add Prism.js:

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

```jsx theme={null}
// In your app entry (e.g., App.jsx or _app.jsx)
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
```

## 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

```jsx theme={null}
import { 
  ArtifactuseAgentMessage, 
  ArtifactusePanel, 
  ArtifactusePanelToggle 
} from 'artifactuse/react'

<ArtifactuseAgentMessage 
  content={message.content}
  messageId={message.id}
  typing={isStreaming}
  onFormSubmit={({ formId, values }) => {}}
  onSocialCopy={({ platform, text }) => {}}
  onMediaOpen={({ type, src }) => {}}
/>

<ArtifactusePanel
  onAIRequest={async ({ prompt, context }) => {}}
  onSave={({ artifactId, data }) => {}}
  onExport={({ artifactId, blob, filename }) => {}}
  externalPreview={true}
/>

<ArtifactusePanelToggle />
```

## Hooks

### useArtifactuse

Access Artifactuse state and methods:

```jsx theme={null}
import { useArtifactuse } from 'artifactuse/react'

function MyComponent() {
  const {
    // State
    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()
  
  return (
    <button onClick={togglePanel}>
      Artifacts ({artifactCount})
    </button>
  )
}
```

## Events

```jsx theme={null}
const { on } = useArtifactuse()

useEffect(() => {
  const unsubscribe = on('ai:request', async ({ prompt, context }) => {
    const response = await yourAI.chat(prompt)
  })
  
  return unsubscribe
}, [])
```

| Event             | Payload                          | Description              |
| ----------------- | -------------------------------- | ------------------------ |
| `ai:request`      | `{ prompt, context, requestId }` | AI assistance requested  |
| `save:request`    | `{ artifactId, data }`           | Save requested           |
| `export:complete` | `{ artifactId, blob, filename }` | Export completed         |
| `form:submit`     | `{ formId, action, values }`     | Form submitted           |
| `form:cancel`     | `{ formId }`                     | Form cancelled           |
| `social:copy`     | `{ platform, text }`             | Social text copied       |
| `media:open`      | `{ type, src, alt, caption }`    | Media opened in lightbox |
| `edit:save`       | `{ artifactId, artifact, code }` | Code saved from edit tab |
| `panel:opened`    | —                                | Panel opened             |
| `panel:closed`    | —                                | Panel closed             |
| `panel:toggled`   | `{ isOpen }`                     | Panel toggled            |

## Full Example

```jsx theme={null}
import { useState, useEffect } from 'react'
import { 
  ArtifactuseProvider,
  ArtifactuseAgentMessage, 
  ArtifactusePanel, 
  ArtifactusePanelToggle,
  useArtifactuse 
} from 'artifactuse/react'
import 'artifactuse/styles'
import './styles.css'

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

function App() {
  return (
    <ArtifactuseProvider config={{ 
      theme: 'dark',
      // branding: true, // Set to false to hide branding (requires license)
    }}>
      <Chat />
    </ArtifactuseProvider>
  )
}

function Chat() {
  const [messages, setMessages] = useState([])
  const { on } = useArtifactuse()
  
  useEffect(() => {
    on('form:submit', ({ formId, values }) => {
      // Send form data back to AI
      sendMessage(`Form submitted: ${JSON.stringify(values)}`)
    })
  }, [])
  
  return (
    <div className="app-container">
      <div className="chat">
        {messages.map(msg => (
          <ArtifactuseAgentMessage 
            key={msg.id}
            content={msg.content}
            messageId={msg.id}
            typing={msg.isStreaming}
          />
        ))}
        
        <ArtifactusePanelToggle />
      </div>
      
      <ArtifactusePanel />
    </div>
  )
}
```

```css theme={null}
/* styles.css */
html, body, #root {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
}

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

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