Skip to main content

Overview

Text input elements capture user-entered text and numbers. Choose the right type based on what you’re collecting—each type provides appropriate validation and UI.
ElementBest ForValidation
textShort text (names, titles)Length, pattern
textareaLong text (descriptions)Length
urlWeb addressesURL format
passwordSensitive data (API keys)Length, pattern
numberNumeric valuesMin/max

Text Input

Single-line text input for short text like usernames, titles, or labels.

Properties

PropertyTypeDescription
idstringUnique identifier (becomes prop name)
inputType'text'Must be 'text'
titlestringField title
descriptionstringHelp text
labelstringInput label
placeholderstringPlaceholder text
defaultValuestringInitial value
validationobjectValidation rules

Validation

RuleTypeDescription
requiredbooleanField must not be empty
minLengthnumberMinimum characters
maxLengthnumberMaximum characters
patternstringRegex pattern to match

Example

linkapp.config.ts
{
  id: "username",
  inputType: "text",
  title: "Username",
  description: "Your display name",
  label: "Username",
  placeholder: "johndoe",
  defaultValue: "",
  validation: {
    required: true,
    minLength: 3,
    maxLength: 20,
    pattern: "^[a-zA-Z0-9_]+$"  // Alphanumeric and underscores
  }
}

Usage in Layout

app/expanded.tsx
type Settings = {
  username: string;
};

export default function ClassicLayout({ username }: AppProps<Settings>) {
  return <div>Welcome, {username}!</div>;
}

Common Patterns

Display name:
{
  id: "displayName",
  inputType: "text",
  title: "Display Name",
  label: "Name",
  placeholder: "John Doe",
  validation: { required: true, maxLength: 50 }
}
Title or heading:
{
  id: "title",
  inputType: "text",
  title: "LinkApp Title",
  label: "Title",
  placeholder: "Enter a title",
  defaultValue: "My LinkApp",
  validation: { maxLength: 100 }
}
Custom label:
{
  id: "buttonText",
  inputType: "text",
  title: "Button Text",
  label: "Text",
  placeholder: "Click me",
  defaultValue: "Learn More",
  validation: { required: true, maxLength: 30 }
}

Textarea

Multi-line text input for longer content like descriptions or messages.

Properties

PropertyTypeDescription
idstringUnique identifier
inputType'textarea'Must be 'textarea'
titlestringField title
descriptionstringHelp text
labelstringInput label
placeholderstringPlaceholder text
defaultValuestringInitial value
validationobjectValidation rules

Validation

RuleTypeDescription
requiredbooleanField must not be empty
minLengthnumberMinimum characters
maxLengthnumberMaximum characters

Example

linkapp.config.ts
{
  id: "bio",
  inputType: "textarea",
  title: "Bio",
  description: "Tell users about yourself",
  label: "Your bio",
  placeholder: "I'm a creator who...",
  defaultValue: "",
  validation: {
    maxLength: 500
  }
}

Usage in Layout

app/expanded.tsx
type Settings = {
  bio: string;
};

export default function ClassicLayout({ bio }: AppProps<Settings>) {
  return (
    <div>
      <p className="bio">{bio}</p>
    </div>
  );
}

Common Patterns

Description field:
{
  id: "description",
  inputType: "textarea",
  title: "Description",
  label: "Describe your app",
  placeholder: "This app helps you...",
  validation: { required: true, maxLength: 300 }
}
Custom message:
{
  id: "welcomeMessage",
  inputType: "textarea",
  title: "Welcome Message",
  label: "Message",
  placeholder: "Welcome! Here's what you need to know...",
  validation: { maxLength: 1000 }
}

URL Input

URL input with built-in validation to ensure valid HTTP/HTTPS addresses.

Properties

PropertyTypeDescription
idstringUnique identifier
inputType'url'Must be 'url'
titlestringField title
descriptionstringHelp text
labelstringInput label
placeholderstringPlaceholder URL
defaultValuestringInitial URL
validationobjectValidation rules

Validation

RuleTypeDescription
requiredbooleanField must not be empty
patternstringAdditional regex pattern
URL inputs automatically validate that the value starts with http:// or https://. Use pattern for additional constraints like requiring HTTPS.

Example

linkapp.config.ts
{
  id: "websiteUrl",
  inputType: "url",
  title: "Website URL",
  description: "Your website address",
  label: "Website",
  placeholder: "https://example.com",
  defaultValue: "",
  validation: {
    required: true,
    pattern: "^https://.*"  // Require HTTPS
  }
}

Usage in Layout

app/expanded.tsx
type Settings = {
  websiteUrl: string;
};

export default function ClassicLayout({ websiteUrl }: AppProps<Settings>) {
  return (
    <a href={websiteUrl} target="_blank" rel="noopener">
      Visit Website
    </a>
  );
}

Common Patterns

External link:
{
  id: "externalUrl",
  inputType: "url",
  title: "External Link",
  label: "URL",
  placeholder: "https://example.com",
  validation: { required: true }
}
API endpoint:
{
  id: "apiEndpoint",
  inputType: "url",
  title: "API Endpoint",
  description: "Your API base URL",
  label: "Endpoint",
  placeholder: "https://api.example.com",
  validation: { required: true, pattern: "^https://.*" }
}

Password Input

Masked input for sensitive data like API keys or credentials.

Properties

PropertyTypeDescription
idstringUnique identifier
inputType'password'Must be 'password'
titlestringField title
descriptionstringHelp text
labelstringInput label
placeholderstringPlaceholder text
defaultValuestringInitial value (masked)
validationobjectValidation rules

Validation

RuleTypeDescription
requiredbooleanField must not be empty
minLengthnumberMinimum characters
maxLengthnumberMaximum characters
patternstringRegex pattern
Values are masked in the UI but transmitted as plain text to your layout. Always handle sensitive data securely.

Example

linkapp.config.ts
{
  id: "apiKey",
  inputType: "password",
  title: "API Key",
  description: "Get your API key from settings.example.com",
  label: "API Key",
  placeholder: "Enter your API key",
  validation: {
    required: true,
    minLength: 20,
    pattern: "^[a-zA-Z0-9]+$"
  }
}

Usage in Layout

app/expanded.tsx
type Settings = {
  apiKey: string;
};

export default function ClassicLayout({ apiKey }: AppProps<Settings>) {
  // Use API key to fetch data
  useEffect(() => {
    fetch("https://api.example.com/data", {
      headers: { Authorization: `Bearer ${apiKey}` },
    });
  }, [apiKey]);

  return <div>Loading data...</div>;
}

Common Patterns

API key:
{
  id: "apiKey",
  inputType: "password",
  title: "API Key",
  description: "Your secret API key",
  label: "Key",
  validation: { required: true, minLength: 16 }
}
Secret token:
{
  id: "secretToken",
  inputType: "password",
  title: "Secret Token",
  label: "Token",
  placeholder: "Enter your secret token",
  validation: { required: true }
}

Number Input

Numeric input with min/max validation.

Properties

PropertyTypeDescription
idstringUnique identifier
inputType'number'Must be 'number'
titlestringField title
descriptionstringHelp text
labelstringInput label
placeholdernumber | stringPlaceholder value
defaultValuenumberInitial value
validationobjectValidation rules

Validation

RuleTypeDescription
requiredbooleanField must not be empty
minnumberMinimum value (inclusive)
maxnumberMaximum value (inclusive)

Example

linkapp.config.ts
{
  id: "itemCount",
  inputType: "number",
  title: "Number of Items",
  description: "How many items to display",
  label: "Count",
  placeholder: 10,
  defaultValue: 5,
  validation: {
    required: true,
    min: 1,
    max: 100
  }
}

Usage in Layout

app/expanded.tsx
type Settings = {
  itemCount: number;
};

export default function ClassicLayout({ itemCount }: AppProps<Settings>) {
  return (
    <div>
      Showing {itemCount} items
      {Array.from({ length: itemCount }).map((_, i) => (
        <div key={i}>Item {i + 1}</div>
      ))}
    </div>
  );
}

Common Patterns

Item limit:
{
  id: "maxItems",
  inputType: "number",
  title: "Maximum Items",
  label: "Max",
  defaultValue: 10,
  validation: { min: 1, max: 50 }
}
Timeout/duration:
{
  id: "timeoutSeconds",
  inputType: "number",
  title: "Timeout",
  description: "Timeout in seconds",
  label: "Seconds",
  defaultValue: 30,
  validation: { min: 5, max: 300 }
}
Percentage:
{
  id: "opacity",
  inputType: "number",
  title: "Opacity",
  description: "Opacity percentage (0-100)",
  label: "Opacity %",
  defaultValue: 100,
  validation: { min: 0, max: 100 }
}

Complete Example

Here’s a contact form using multiple text input types:
linkapp.config.ts
export default {
  settings: {
    title: "Contact Form",
    elements: [
      {
        id: "formTitle",
        inputType: "text",
        title: "Form Title",
        label: "Title",
        defaultValue: "Get in Touch",
        validation: { required: true, maxLength: 50 },
      },
      {
        id: "description",
        inputType: "textarea",
        title: "Form Description",
        label: "Description",
        placeholder: "We'd love to hear from you...",
        validation: { maxLength: 200 },
      },
      {
        id: "submitUrl",
        inputType: "url",
        title: "Submit URL",
        description: "Where form submissions are sent",
        label: "Endpoint",
        validation: { required: true, pattern: "^https://.*" },
      },
      {
        id: "apiKey",
        inputType: "password",
        title: "API Key",
        description: "Your form service API key",
        label: "Key",
        validation: { required: true, minLength: 20 },
      },
      {
        id: "maxSubmissions",
        inputType: "number",
        title: "Submission Limit",
        description: "Maximum submissions per user",
        label: "Max",
        defaultValue: 1,
        validation: { min: 1, max: 10 },
      },
    ],
  },
};

Validation Error Messages

When validation fails, users see helpful messages:
RuleExample Error
required: true”This field is required”
minLength: 3”Must be at least 3 characters”
maxLength: 100”Must be at most 100 characters”
min: 1”Must be at least 1”
max: 100”Must be at most 100”
pattern: '^[a-z]+$'”Invalid format”
Add clear description text to help users understand what’s expected and avoid validation errors.

Next Steps