# Render a Primitive

Turn a primitive's slots into parts in your framework, pass options, and read state.

[Define a Primitive](/docs/core/kernel/define-a-primitive) gave the copy button its options, state and slots. Now let's put it on the page. Choose your framework in the page header, and the code below follows it.

## Install the Adapter

An **adapter** connects a primitive to your framework. Install the one for yours:

**React**

```bash
npm add @ui-sdk/react
```

**Vue**

```bash
npm add @ui-sdk/vue
```

**Svelte**

```bash
npm add @ui-sdk/svelte
```

**Solid**

```bash
npm add @ui-sdk/solid
```

**Web Components**

```bash
npm add @ui-sdk/web
```

## Create the Parts

`createParts` turns each slot into a **part**. Pass it the primitive and the element each part renders:

**React**

```ts title="copy-button-parts.ts"
"use client"

import { createParts } from "@ui-sdk/react/primitive"
import { copyButton } from "./copy-button"

const { Root: CopyButton } = createParts(copyButton, { root: "button" })

export { CopyButton }
```

**Vue**

```ts title="copy-button-parts.ts"
import { createParts } from "@ui-sdk/vue/primitive"
import { copyButton } from "./copy-button"

const { Root: CopyButton } = createParts(copyButton, { root: "button" })

export { CopyButton }
```

**Svelte**

```ts title="copy-button-parts.ts"
import { createParts } from "@ui-sdk/svelte/primitive"
import { copyButton } from "./copy-button"

const { Root: CopyButton } = createParts(copyButton, { root: "button" })

export { CopyButton }
```

**Solid**

```ts title="copy-button-parts.ts"
import { createParts } from "@ui-sdk/solid/primitive"
import { copyButton } from "./copy-button"

const { Root: CopyButton } = createParts(copyButton, { root: "button" })

export { CopyButton }
```

**Web Components**

```ts title="copy-button-parts.ts"
import { createParts, wrappedButton } from "@ui-sdk/web"
import { copyButton } from "./copy-button"

createParts(copyButton, {
  root: { tag: "copy-button", target: wrappedButton },
})
```

`createParts` registers a custom element for each slot you map. `wrappedButton` puts the root's behavior and attributes on a native button inside the element. Import this file from your app's browser entry point.

`Root` creates the primitive's instance and shares it with the parts inside. Every other slot becomes a part named in Pascal case, so a `star` slot becomes `Star`.

## Pass Options

The primitive's options become the part's props, next to the element's own:

**React**

```tsx
<CopyButton text="npm add @ui-sdk/core" onCopy={(text) => console.log(text)}>
  Copy
</CopyButton>
```

**Vue**

```vue
<CopyButton
  text="npm add @ui-sdk/core"
  @copy="(text) => console.log(text)"
>Copy</CopyButton>
```

A callback option becomes an event, so `onCopy` is `@copy`.

**Svelte**

```svelte
<CopyButton text="npm add @ui-sdk/core" onCopy={(text) => console.log(text)}
  >Copy</CopyButton
>
```

**Solid**

```tsx
<CopyButton text="npm add @ui-sdk/core" onCopy={(text) => console.log(text)}>
  Copy
</CopyButton>
```

**Web Components**

```html
<copy-button text="npm add @ui-sdk/core">
  <button>Copy</button>
</copy-button>
```

A `"string"` option reads from its attribute, and a callback option fires as an event on the element.

## Read the State

The root's slot returns `copied` from its `state`, so the button's content can follow it:

**React**

```tsx
<CopyButton text="npm add @ui-sdk/core">
  {({ copied }) => (copied ? "Copied" : "Copy")}
</CopyButton>
```

**Vue**

```vue
<CopyButton v-slot="{ state }" text="npm add @ui-sdk/core">
  {{ state.copied ? "Copied" : "Copy" }}
</CopyButton>
```

**Svelte**

```svelte
<CopyButton text="npm add @ui-sdk/core">
  {#snippet children(state)}{state.copied ? "Copied" : "Copy"}{/snippet}
</CopyButton>
```

**Solid**

```tsx
<CopyButton text="npm add @ui-sdk/core">
  {(state) => (state.copied ? "Copied" : "Copy")}
</CopyButton>
```

**Web Components**

On web components, the content is your own HTML. Show state through the attributes the part sets, as [Style a Component](/docs/core/kernel/style-a-component) shows.

## Write Your Own Part

`createParts` is enough when each slot maps to one element. When a part needs logic of its own, such as rendering a list from data, write it yourself and connect it to the same primitive. [Custom Parts](/docs/custom-parts) shows how in your framework.

## Render on the Server

Parts render their attributes into the server's HTML, so the page shows the right state before your framework hydrates it. On web components, you send the markup and the element connects its behavior once its module loads. [Server Rendering](/docs/server-rendering) covers the setup for your framework.

## Next

The button works, but it has no styles yet. Next, [Style a Component](/docs/core/kernel/style-a-component) styles it from the attributes it renders.
