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

# Advanced Elements

> Arrays, integrations, conditional display, and specialized elements

## Overview

Advanced elements provide complex functionality like dynamic lists, third-party integrations, and conditional forms. These elements unlock powerful features for sophisticated LinkApps.

| Element              | Use Case                                                  |
| -------------------- | --------------------------------------------------------- |
| `array`              | Dynamic lists of structured items (FAQs, links, products) |
| `integration`        | Connect third-party services (email marketing, etc.)      |
| `conditionalDisplay` | Show/hide elements based on other values                  |
| `file`               | Upload images or documents                                |
| `button`             | Trigger actions or workflows                              |

## Array

Dynamic array of structured inputs for collecting lists of items. Perfect for FAQs, social links, product lists, or any repeating data.

### Properties

| Property         | Type      | Description                           |
| ---------------- | --------- | ------------------------------------- |
| `id`             | `string`  | Unique identifier (becomes prop name) |
| `inputType`      | `'array'` | Must be `'array'`                     |
| `title`          | `string`  | Field title                           |
| `description`    | `string`  | Help text                             |
| `label`          | `string`  | Label for the array                   |
| `defaultValue`   | `array`   | Initial array values                  |
| `array_options`  | `object`  | Array UI configuration                |
| `array_elements` | `array`   | Element definitions for each item     |
| `validation`     | `object`  | Validation rules                      |

### Array Options

Configure the array UI in the admin:

| Property                      | Type     | Description                             |
| ----------------------------- | -------- | --------------------------------------- |
| `min`                         | `number` | Minimum items required                  |
| `max`                         | `number` | Maximum items allowed                   |
| `add_item_button_text`        | `string` | "Add" button text (empty array)         |
| `add_second_item_button_text` | `string` | "Add" button text (after first item)    |
| `add_item_title`              | `string` | Add dialog title                        |
| `edit_item_title`             | `string` | Edit dialog title                       |
| `item_format`                 | `string` | Display template (e.g., `{{question}}`) |

### Validation

| Rule       | Type      | Description                                        |
| ---------- | --------- | -------------------------------------------------- |
| `required` | `boolean` | Array must have at least one item                  |
| `maxSize`  | `number`  | Maximum items (alternative to `array_options.max`) |

### Example: Social Links

```ts linkapp.config.ts theme={"system"}
{
  id: "socialLinks",
  inputType: "array",
  title: "Social Links",
  description: "Add your social media profiles",
  label: "Social profiles",
  array_options: {
    min: 1,
    max: 5,
    add_item_button_text: "Add social link",
    add_second_item_button_text: "Add another link",
    item_format: "{{platform}}: {{url}}"
  },
  array_elements: [
    {
      id: "platform",
      inputType: "select",
      title: "Platform",
      label: "Social platform",
      options: [
        { label: "Twitter", value: "twitter" },
        { label: "Instagram", value: "instagram" },
        { label: "TikTok", value: "tiktok" },
        { label: "LinkedIn", value: "linkedin" }
      ],
      validation: { required: true }
    },
    {
      id: "url",
      inputType: "url",
      title: "Profile URL",
      label: "URL",
      placeholder: "https://twitter.com/username",
      validation: { required: true }
    }
  ],
  validation: {
    required: true
  }
}
```

**Usage in layout:**

```tsx app/expanded.tsx theme={"system"}
type SocialLink = {
  platform: 'twitter' | 'instagram' | 'tiktok' | 'linkedin'
  url: string
}

type Settings = {
  socialLinks: SocialLink[]
}

export default function ClassicLayout({ socialLinks }: AppProps<Settings>) {
  return (
    <div className="social-links">
      <h2>Follow me:</h2>
      {socialLinks.map((link, index) => (
        <a key={index} href={link.url} className={`social-${link.platform}`}>
          {link.platform}
        </a>
      ))}
    </div>
  )
}
```

### Example: FAQ List

```ts linkapp.config.ts theme={"system"}
{
  id: "questions_list",
  inputType: "array",
  title: "Questions",
  validation: {
    required: true,
    maxSize: 20
  },
  array_options: {
    add_item_button_text: "Add a question",
    add_item_title: "Add question",
    add_second_item_button_text: "Add another question",
    edit_item_title: "Edit question",
    item_format: "{{question}}"  // Shows question text in list
  },
  array_elements: [
    {
      id: "question",
      title: "Question",
      inputType: "text",
      validation: {
        required: true,
        minLength: 1,
        maxLength: 200
      }
    },
    {
      id: "answer",
      title: "Answer",
      inputType: "textarea",
      validation: {
        required: true,
        minLength: 1,
        maxLength: 800
      }
    }
  ]
}
```

**Usage in layout:**

```tsx app/expanded.tsx theme={"system"}
type Question = {
  question: string
  answer: string
}

type FAQSettings = {
  questions_list: Question[]
}

export default function ClassicLayout({ questions_list }: AppProps<FAQSettings>) {
  return (
    <div className="faq">
      <h1>Frequently Asked Questions</h1>
      {questions_list.map((item, index) => (
        <details key={index}>
          <summary>{item.question}</summary>
          <p>{item.answer}</p>
        </details>
      ))}
    </div>
  )
}
```

<Tip>
  Use `item_format` with `{{fieldId}}` syntax to show a preview of each item in the admin list view.
</Tip>

## Conditional Display

Show or hide elements based on the value of other elements. Creates dynamic forms that adapt to user choices.

### Properties

| Property    | Type                                    | Description                               |
| ----------- | --------------------------------------- | ----------------------------------------- |
| `dependsOn` | `string`                                | ID of the element this depends on         |
| `value`     | `string \| boolean`                     | Value that triggers display               |
| `operator`  | `'equals' \| 'notEquals' \| 'contains'` | Comparison operator (default: `'equals'`) |

Add `conditionalDisplay` to any element to control its visibility.

### Example: Conditional Email Input

```ts linkapp.config.ts theme={"system"}
elements: [
  {
    id: "enableNotifications",
    inputType: "switch",
    title: "Notifications",
    label: "Enable email notifications",
    defaultValue: false
  },
  {
    id: "notificationEmail",
    inputType: "text",
    title: "Email Address",
    label: "Email",
    placeholder: "you@example.com",
    validation: {
      required: true
    },
    // Only show if enableNotifications is true
    conditionalDisplay: {
      dependsOn: "enableNotifications",
      value: true,
      operator: "equals"
    }
  }
]
```

### Example: Conditional Based on Select

```ts linkapp.config.ts theme={"system"}
elements: [
  {
    id: "integrationProvider",
    inputType: "select",
    title: "Integration Provider",
    options: [
      { label: "Mailchimp", value: "mailchimp" },
      { label: "SendGrid", value: "sendgrid" },
      { label: "Custom API", value: "custom" }
    ]
  },
  {
    id: "customApiEndpoint",
    inputType: "url",
    title: "Custom API Endpoint",
    placeholder: "https://api.example.com/notify",
    validation: { required: true },
    // Only show if integrationProvider is 'custom'
    conditionalDisplay: {
      dependsOn: "integrationProvider",
      value: "custom"
    }
  },
  {
    id: "customApiKey",
    inputType: "text",
    title: "API Key",
    placeholder: "Enter your API key",
    // Also only show for custom
    conditionalDisplay: {
      dependsOn: "integrationProvider",
      value: "custom"
    }
  }
]
```

### Operators

| Operator    | Description           | Example                                                |
| ----------- | --------------------- | ------------------------------------------------------ |
| `equals`    | Exact match (default) | `value: true` shows when field is true                 |
| `notEquals` | Does not match        | `value: "none"` shows when field is not "none"         |
| `contains`  | Array contains value  | `value: "advanced"` shows if array includes "advanced" |

<Tip>
  Use conditional display to reduce form complexity and show users only relevant fields.
</Tip>

## Integration

Connect to third-party services like email marketing platforms. Requires users to have the integration already set up in their Linktree account.

### Properties

| Property      | Type            | Description                           |
| ------------- | --------------- | ------------------------------------- |
| `id`          | `string`        | Unique identifier                     |
| `inputType`   | `'integration'` | Must be `'integration'`               |
| `capability`  | `string`        | Required integration capability       |
| `vendor`      | `string`        | Specific vendor identifier (optional) |
| `title`       | `string`        | Field title                           |
| `description` | `string`        | Help text                             |

### Example

```ts linkapp.config.ts theme={"system"}
{
  id: "emailIntegration",
  inputType: "integration",
  title: "Email Marketing",
  description: "Connect your email marketing service to collect subscribers",
  capability: "MANAGE_EMAIL_SUBSCRIBERS",
  vendor: "mailchimp"  // Optional: specific vendor
}
```

<Note>
  Users must have the integration already connected in their Linktree account. This element lets them select which integration to use with your LinkApp.
</Note>

## File Upload

Upload images, documents, or other file types.

### Properties

| Property      | Type       | Description          |
| ------------- | ---------- | -------------------- |
| `id`          | `string`   | Unique identifier    |
| `inputType`   | `'file'`   | Must be `'file'`     |
| `title`       | `string`   | Field title          |
| `description` | `string`   | Help text            |
| `label`       | `string`   | Input label          |
| `accept`      | `string[]` | Accepted file types  |
| `multiple`    | `boolean`  | Allow multiple files |
| `validation`  | `object`   | Validation rules     |

### Example

```ts linkapp.config.ts theme={"system"}
{
  id: "bannerImage",
  inputType: "file",
  title: "Banner Image",
  description: "Upload a banner image for your LinkApp",
  label: "Choose image",
  accept: ["image/png", "image/jpeg", "image/webp"],
  multiple: false,
  validation: {
    required: true
  }
}
```

## Button

Interactive button element that triggers actions.

### Properties

| Property    | Type       | Description          |
| ----------- | ---------- | -------------------- |
| `id`        | `string`   | Unique identifier    |
| `inputType` | `'button'` | Must be `'button'`   |
| `label`     | `string`   | Button text          |
| `action`    | `object`   | Action configuration |

### Action Properties

| Property         | Type            | Description            |
| ---------------- | --------------- | ---------------------- |
| `on`             | `'click'`       | Interaction event      |
| `type`           | `'update-link'` | Action type            |
| `data.link_type` | `string`        | Link type to update to |

### Example

```ts linkapp.config.ts theme={"system"}
{
  id: "upgradeButton",
  inputType: "button",
  label: "Upgrade to Pro Version",
  action: {
    on: "click",
    type: "update-link",
    data: {
      link_type: "pro-version-app"
    }
  }
}
```

## Complete Example: Advanced FAQ App

Here's a complete example using arrays and conditional display:

```ts linkapp.config.ts theme={"system"}
export default {
  settings: {
    title: "FAQ Manager",
    icon: "question-mark",
    uses_url: false,
    elements: [
      // Array of FAQ items
      {
        id: "questions_list",
        inputType: "array",
        validation: {
          required: true,
          maxSize: 20
        },
        array_options: {
          add_item_button_text: "Add a question",
          add_item_title: "Add question",
          item_format: "{{question}}"
        },
        array_elements: [
          {
            id: "question",
            title: "Question",
            inputType: "text",
            validation: { required: true, maxLength: 200 }
          },
          {
            id: "answer",
            title: "Answer",
            inputType: "textarea",
            validation: { required: true, maxLength: 800 }
          }
        ]
      },

      // Enable search toggle
      {
        id: "enableSearch",
        inputType: "switch",
        title: "Search Options",
        label: "Enable question search",
        defaultValue: false
      },

      // Search placeholder (conditional)
      {
        id: "searchPlaceholder",
        inputType: "text",
        title: "Search Placeholder",
        label: "Placeholder text",
        defaultValue: "Search questions...",
        conditionalDisplay: {
          dependsOn: "enableSearch",
          value: true
        }
      },

      // Enable categories toggle
      {
        id: "enableCategories",
        inputType: "switch",
        title: "Organization",
        label: "Group questions by category",
        defaultValue: false
      },

      // Category list (conditional)
      {
        id: "categories",
        inputType: "array",
        title: "Categories",
        description: "Define question categories",
        conditionalDisplay: {
          dependsOn: "enableCategories",
          value: true
        },
        array_options: {
          add_item_button_text: "Add category",
          item_format: "{{name}}"
        },
        array_elements: [
          {
            id: "name",
            inputType: "text",
            title: "Category Name",
            validation: { required: true, maxLength: 50 }
          }
        ]
      }
    ]
  }
}
```

## Validation Strategies

### Required Arrays

```ts theme={"system"}
{
  id: "items",
  inputType: "array",
  validation: {
    required: true  // At least one item required
  }
}
```

### Array Size Limits

```ts theme={"system"}
{
  id: "items",
  inputType: "array",
  array_options: {
    min: 1,   // Minimum items
    max: 10   // Maximum items
  }
}
```

Or use `validation.maxSize`:

```ts theme={"system"}
{
  id: "items",
  inputType: "array",
  validation: {
    maxSize: 10
  }
}
```

### Nested Validation

Array elements can have their own validation:

```ts theme={"system"}
array_elements: [
  {
    id: "email",
    inputType: "text",
    validation: {
      required: true,
      pattern: "^[^@]+@[^@]+\\.[^@]+$"  // Email format
    }
  }
]
```

## Best Practices

### Array Design

```ts theme={"system"}
// ✅ Good - clear item format
array_options: {
  item_format: "{{question}}"  // Shows question text
}

// ✅ Good - descriptive button text
array_options: {
  add_item_button_text: "Add a social link",
  add_second_item_button_text: "Add another social link"
}
```

### Conditional Display

```ts theme={"system"}
// ✅ Good - progressive disclosure
{
  id: "advancedMode",
  inputType: "switch",
  label: "Show advanced options"
},
{
  id: "advancedSettings",
  inputType: "text",
  conditionalDisplay: {
    dependsOn: "advancedMode",
    value: true
  }
}
```

### Array Element Names

```ts theme={"system"}
// ✅ Good - descriptive IDs
array_elements: [
  { id: "question", inputType: "text" },
  { id: "answer", inputType: "textarea" }
]

// ❌ Avoid - unclear
array_elements: [
  { id: "q", inputType: "text" },
  { id: "a", inputType: "textarea" }
]
```

## Type Safety

Define array item types:

```ts theme={"system"}
type Question = {
  question: string
  answer: string
}

type SocialLink = {
  platform: string
  url: string
}

type Settings = {
  questions_list: Question[]
  socialLinks: SocialLink[]
  enableSearch: boolean
  searchPlaceholder: string  // Only shown if enableSearch is true
}

export default function ClassicLayout(props: AppProps<Settings>) {
  const { questions_list, socialLinks, enableSearch, searchPlaceholder } = 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="Toggles" icon="toggle-on" href="/essentials/settings/toggles">
    Switch and link behavior elements
  </Card>

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