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

# Toggle Elements

> Switch and link behavior elements for on/off controls

## Overview

Toggle elements provide simple on/off controls. They're perfect for enabling/disabling features or choosing between two states.

| Element        | Use Case                                  | Returns                          |
| -------------- | ----------------------------------------- | -------------------------------- |
| `switch`       | Enable/disable features                   | `boolean`                        |
| `linkBehavior` | Embed vs. direct link (Linktree-specific) | `'embedLabel' \| 'linkOffLabel'` |

## Switch Toggle

Boolean toggle for enabling/disabling features. Provides a visual on/off switch UI.

### Properties

| Property       | Type       | Description                            |
| -------------- | ---------- | -------------------------------------- |
| `id`           | `string`   | Unique identifier (becomes prop name)  |
| `inputType`    | `'switch'` | Must be `'switch'`                     |
| `title`        | `string`   | Field title                            |
| `description`  | `string`   | Help text                              |
| `label`        | `string`   | Label text next to switch              |
| `defaultValue` | `boolean`  | Initial state (true = on, false = off) |
| `validation`   | `object`   | Validation rules                       |

### Validation

| Rule       | Type      | Description                            |
| ---------- | --------- | -------------------------------------- |
| `required` | `boolean` | Switch must be ON (value must be true) |

<Note>
  Setting `required: true` means the switch **must be ON**. This is useful for terms acceptance or required opt-ins. Most switches should not be required.
</Note>

### Example

```ts linkapp.config.ts theme={"system"}
{
  id: "showTitle",
  inputType: "switch",
  title: "Display Options",
  description: "Toggle title visibility",
  label: "Show title",
  defaultValue: true,
  validation: {
    required: false  // Optional - can be on or off
  }
}
```

### Usage in Layout

```tsx app/expanded.tsx theme={"system"}
type Settings = {
  showTitle: boolean
}

export default function ClassicLayout({ showTitle }: AppProps<Settings>) {
  return (
    <div>
      {showTitle && <h1>My LinkApp</h1>}
      <p>Content</p>
    </div>
  )
}
```

### Common Patterns

**Feature toggle:**

```ts theme={"system"}
{
  id: "enableNotifications",
  inputType: "switch",
  title: "Notifications",
  label: "Enable email notifications",
  defaultValue: false
}
```

**Display option:**

```ts theme={"system"}
{
  id: "showDescription",
  inputType: "switch",
  title: "Display Options",
  description: "Show or hide the description text",
  label: "Show description",
  defaultValue: true
}
```

**Required acceptance:**

```ts theme={"system"}
{
  id: "agreeToTerms",
  inputType: "switch",
  title: "Terms of Service",
  description: "You must accept the terms to continue",
  label: "I agree to the Terms of Service",
  defaultValue: false,
  validation: {
    required: true  // Must be ON
  }
}
```

**Privacy setting:**

```ts theme={"system"}
{
  id: "publicProfile",
  inputType: "switch",
  title: "Privacy",
  description: "Make your profile visible to everyone",
  label: "Public profile",
  defaultValue: false
}
```

### Multiple Switches

Group related switches under one title:

```ts theme={"system"}
elements: [
  {
    id: "showTitle",
    inputType: "switch",
    title: "Display Options",  // Section title
    description: "Control what appears on your LinkApp",
    label: "Show title",
    defaultValue: true
  },
  {
    id: "showDescription",
    inputType: "switch",
    title: "",  // Same section, no title
    label: "Show description",
    defaultValue: true
  },
  {
    id: "showAuthor",
    inputType: "switch",
    title: "",  // Same section
    label: "Show author name",
    defaultValue: false
  }
]
```

**Usage:**

```tsx theme={"system"}
type Settings = {
  showTitle: boolean
  showDescription: boolean
  showAuthor: boolean
}

export default function ClassicLayout({
  showTitle,
  showDescription,
  showAuthor
}: AppProps<Settings>) {
  return (
    <div>
      {showTitle && <h1>Title</h1>}
      {showDescription && <p>Description</p>}
      {showAuthor && <span>By Author</span>}
    </div>
  )
}
```

### Switch vs. Checkbox

When to use switch vs. single checkbox:

| Use Switch When              | Use Checkbox When         |
| ---------------------------- | ------------------------- |
| Enabling/disabling a feature | Accepting terms/agreement |
| Toggling display options     | Opting into something     |
| Turning something on/off     | Confirming understanding  |
| Immediate effect expected    | Explicit consent required |

```ts theme={"system"}
// ✅ Switch - for feature toggle
{ id: "enableDarkMode", inputType: "switch", label: "Enable dark mode" }

// ✅ Checkbox - for acceptance
{ id: "terms", inputType: "checkbox", options: [{ label: "I agree to terms", value: "agreed" }] }
```

## Link Behavior

Linktree-specific control for how links behave when clicked. Users choose between showing your LinkApp UI (embed) or navigating directly to the URL (link off).

### Properties

| Property             | Type                             | Description                |
| -------------------- | -------------------------------- | -------------------------- |
| `id`                 | `string`                         | Unique identifier          |
| `inputType`          | `'linkBehavior'`                 | Must be `'linkBehavior'`   |
| `title`              | `string`                         | Field title                |
| `description`        | `string`                         | Help text                  |
| `label`              | `string`                         | Label for radio group      |
| `defaultValue`       | `'embedLabel' \| 'linkOffLabel'` | Initial behavior           |
| `linkBehaviorLabels` | `object`                         | Labels for the two options |
| `validation`         | `object`                         | Validation rules           |

### Link Behavior Labels

| Property       | Type     | Description                  |
| -------------- | -------- | ---------------------------- |
| `embedLabel`   | `string` | Label for showing LinkApp UI |
| `linkOffLabel` | `string` | Label for direct navigation  |

<Note>
  **Link Behavior** lets users choose:

  * **Embed** (`embedLabel`): Display your LinkApp's UI when clicked (renders your layout)
  * **Link Off** (`linkOffLabel`): Navigate directly to the URL (bypass your layout)

  If not specified, defaults to `embedLabel` (show your LinkApp).
</Note>

### Example

```ts linkapp.config.ts theme={"system"}
{
  id: "linkBehavior",
  inputType: "linkBehavior",
  title: "Link Behavior",
  description: "How should this link behave when clicked?",
  label: "Click behavior",
  defaultValue: "embedLabel",
  linkBehaviorLabels: {
    embedLabel: "Show custom video player",
    linkOffLabel: "Go directly to YouTube"
  },
  validation: {
    required: true
  }
}
```

### Usage in Layout

```tsx app/expanded.tsx theme={"system"}
type Settings = {
  linkBehavior: 'embedLabel' | 'linkOffLabel'
}

export default function ClassicLayout({
  linkBehavior,
  linkUrl
}: AppProps<Settings>) {
  // If user chose "link off", redirect immediately
  if (linkBehavior === 'linkOffLabel') {
    window.location.href = linkUrl
    return null
  }

  // Otherwise, show your custom UI
  return (
    <div className="custom-video-player">
      <VideoEmbed url={linkUrl} />
    </div>
  )
}
```

### Common Use Cases

**Video embed:**

```ts theme={"system"}
{
  id: "videoDisplay",
  inputType: "linkBehavior",
  title: "Video Display",
  description: "Choose how to display YouTube videos",
  linkBehaviorLabels: {
    embedLabel: "Show video player on Linktree",
    linkOffLabel: "Open YouTube in new tab"
  },
  defaultValue: "embedLabel"
}
```

**Content preview:**

```ts theme={"system"}
{
  id: "contentBehavior",
  inputType: "linkBehavior",
  title: "Content Preview",
  linkBehaviorLabels: {
    embedLabel: "Show article preview",
    linkOffLabel: "Go directly to article"
  },
  defaultValue: "embedLabel"
}
```

**Social media:**

```ts theme={"system"}
{
  id: "socialEmbed",
  inputType: "linkBehavior",
  title: "Social Post Display",
  description: "Display Instagram post or link to it",
  linkBehaviorLabels: {
    embedLabel: "Embed Instagram post",
    linkOffLabel: "Open Instagram post"
  },
  defaultValue: "embedLabel"
}
```

### When to Use

Use `linkBehavior` when:

✅ Your LinkApp embeds or displays content from the URL
✅ Users might want to bypass your UI and go straight to the source
✅ You're building a media player, content previewer, or social embed

Don't use when:

❌ Your LinkApp doesn't use the `linkUrl` at all
❌ Going directly to the URL doesn't make sense
❌ Your LinkApp is purely decorative

### Validation

| Rule       | Type      | Description                 |
| ---------- | --------- | --------------------------- |
| `required` | `boolean` | A behavior must be selected |

Typically, `linkBehavior` should have `validation: { required: true }` so users explicitly choose their preference.

## Complete Example

Here's a video embed LinkApp using both toggle types:

```ts linkapp.config.ts theme={"system"}
export default {
  settings: {
    title: "Video Player",
    uses_url: true,  // This app uses the linkUrl prop
    elements: [
      // Link behavior - embed vs. direct link
      {
        id: "linkBehavior",
        inputType: "linkBehavior",
        title: "Link Behavior",
        description: "Choose how videos open",
        linkBehaviorLabels: {
          embedLabel: "Play video in Linktree",
          linkOffLabel: "Open YouTube directly"
        },
        defaultValue: "embedLabel",
        validation: { required: true }
      },

      // Feature switches
      {
        id: "autoplay",
        inputType: "switch",
        title: "Playback Options",
        label: "Autoplay video",
        defaultValue: false
      },
      {
        id: "showControls",
        inputType: "switch",
        title: "",  // Same section
        label: "Show player controls",
        defaultValue: true
      },
      {
        id: "loop",
        inputType: "switch",
        title: "",  // Same section
        label: "Loop video",
        defaultValue: false
      }
    ]
  }
}
```

**Layout implementation:**

```tsx app/expanded.tsx theme={"system"}
type VideoSettings = {
  linkBehavior: 'embedLabel' | 'linkOffLabel'
  autoplay: boolean
  showControls: boolean
  loop: boolean
}

export default function ClassicLayout({
  linkBehavior,
  linkUrl,
  autoplay,
  showControls,
  loop
}: AppProps<VideoSettings>) {
  // Direct link - redirect to YouTube
  if (linkBehavior === 'linkOffLabel') {
    window.location.href = linkUrl
    return null
  }

  // Embed - show custom player
  return (
    <div className="video-player">
      <VideoEmbed
        url={linkUrl}
        autoplay={autoplay}
        controls={showControls}
        loop={loop}
      />
    </div>
  )
}
```

## Best Practices

### Use Clear Labels

```ts theme={"system"}
// ✅ Good - descriptive
{ label: "Enable email notifications" }
{ label: "Show author name and profile picture" }

// ❌ Unclear
{ label: "Notifications" }
{ label: "Author" }
```

### Set Sensible Defaults

```ts theme={"system"}
// ✅ Good - off by default for optional features
{ id: "betaFeatures", defaultValue: false }

// ✅ Good - on by default for core features
{ id: "showTitle", defaultValue: true }
```

### Group Related Switches

Use a single `title` for the group, empty strings for subsequent items:

```ts theme={"system"}
{
  id: "showTitle",
  title: "Display Options",  // Group title
  label: "Show title"
},
{
  id: "showDate",
  title: "",  // Same group
  label: "Show date"
}
```

### Link Behavior Labels Should Be Specific

```ts theme={"system"}
// ✅ Good - tells users exactly what happens
linkBehaviorLabels: {
  embedLabel: "Play video in Linktree",
  linkOffLabel: "Open YouTube in new tab"
}

// ❌ Too generic
linkBehaviorLabels: {
  embedLabel: "Embed",
  linkOffLabel: "Link"
}
```

## Type Safety

Define boolean types for switches:

```ts theme={"system"}
type MySettings = {
  showTitle: boolean
  enableNotifications: boolean
  autoplay: boolean
  linkBehavior: 'embedLabel' | 'linkOffLabel'
}

export default function ClassicLayout(props: AppProps<MySettings>) {
  // Full type safety ✨
  const { showTitle, enableNotifications, autoplay, linkBehavior } = props

  return <div>...</div>
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Text Inputs" icon="keyboard" href="/essentials/settings/text-inputs">
    Text, textarea, URL, and number inputs
  </Card>

  <Card title="Selection Controls" icon="list-check" href="/essentials/settings/selections">
    Select, radio, and checkbox elements
  </Card>

  <Card title="Advanced Elements" icon="layer-group" href="/essentials/settings/advanced">
    Arrays, integrations, and conditional display
  </Card>

  <Card title="Back to Reference" icon="arrow-left" href="/essentials/settings-reference">
    Return to settings reference overview
  </Card>
</CardGroup>
