Skip to main content
Add configurable workspace settings to allow users to customize your app at the workspace level. Settings are defined using a workspace settings schema at src/app.settings.ts and displayed with form components from experimental_useWorkspaceSettingsForm(). Unlike regular forms in dialogs, workspace settings forms automatically save changes and don’t require a submit button or onSubmit handler. Each field saves individually:
  • Text inputs and number inputs save onBlur (when the user leaves the field)
  • Toggles, checkboxes, and comboboxes save onChange (immediately when changed)
Only workspace admins can edit workspace settings. However, all workspace members can view the settings.
The Workspace Settings API is experimental and may change in the future. Please don’t use it in production versions of your app.

Example: Basic Workspace Settings

First, define your settings schema. This must be in a file called app.settings.ts at src/app.settings.ts:
app.settings.ts
import { Settings, type SettingsSchema } from "attio";

const appSettingsSchema = {
  workspace: {
    team_name: Settings.string(),
    environment: Settings.string(),
    auto_sync_enabled: Settings.boolean(),
    sync_interval_minutes: Settings.number(),
  },
} satisfies SettingsSchema;

export default appSettingsSchema;
Then, create your workspace settings page to display these settings in a configurable form:
workspace-settings.tsx
import React from "react";
import { experimental_useWorkspaceSettingsForm } from "attio/client";
import type { App } from "attio";

export const workspaceSettings: App.Settings.Workspace = {
  Page,
};

function Page() {
  const {
    Form,
    Section,
    TextInput,
    Toggle,
    NumberInput,
  } = experimental_useWorkspaceSettingsForm();

  return (
    <Form>
      <Section title="General" description="Basic workspace settings.">
        <TextInput
          label="Team name"
          name="team_name"
          minLength={2}
          maxLength={50}
        />
        <TextInput
          label="Environment"
          name="environment"
          placeholder="production"
        />
      </Section>

      <Section title="Sync Settings" description="Control how data syncs.">
        <Toggle
          label="Enable automatic sync"
          name="auto_sync_enabled"
          description="Automatically sync data in the background."
        />
        <NumberInput
          label="Sync interval (minutes)"
          name="sync_interval_minutes"
          min={5}
          max={1440}
          placeholder={60}
        />
      </Section>
    </Form>
  );
}
Finally, register it in your app.ts:
app.ts
import type { App } from "attio";
import { workspaceSettings } from "./workspace-settings";

export const app: App = {
  settings: {
    workspace: workspaceSettings,
  },
  // ... other app configuration
};
The process to create workspace settings is:
  1. Define a workspace settings schema at src/app.settings.ts
  2. Create a workspace settings object with a Page
  3. Use experimental_useWorkspaceSettingsForm() to get form components
  4. Wrap your settings inputs in the <Form/> and organize with <Section/> components
  5. Register the settings in your app.ts

Validation

Unlike regular forms where validation is defined in the schema, workspace settings validation is specified directly on the input components:
workspace-settings-validation.tsx
function Page() {
  const { Form, Section, TextInput, NumberInput } = experimental_useWorkspaceSettingsForm();

  return (
    <Form>
      <Section title="Configuration">
        {/* String validation */}
        <TextInput
          label="Organization name"
          name="organization_name"
          minLength={2}
          maxLength={100}
        />

        {/* URL validation */}
        <TextInput
          label="Webhook URL"
          name="webhook_url"
          type="url"
          url
        />

        {/* Multiline text with character limit */}
        <TextInput
          label="Description"
          name="description"
          multiline
          maxLength={500}
        />

        {/* Number validation */}
        <NumberInput
          label="Timeout (seconds)"
          name="timeout_seconds"
          min={1}
          max={300}
        />
      </Section>
    </Form>
  );
}

Available Components

Workspace settings forms support the following components:

Input Components

Layout Components

Utility Components

  • <Button /> - Action buttons for additional functionality
  • <WithState /> - Access form state for conditional rendering

Accessing Settings in Your App

Once your workspace settings are configured, you can access them in different ways:

With Real-time Updates

In React components, use the experimental_useWorkspaceSettings() hook to get settings that automatically update when changed:
widget.tsx
import { experimental_useWorkspaceSettings, Widget } from "attio/client";

export const Widget = () => {
  const settings = experimental_useWorkspaceSettings();
  
  // Access your settings with full type safety
  // Automatically re-renders when settings change
  return (
    <Widget.TextWidget>
      <Widget.Text.Primary>
        Team: {settings.team_name}
      </Widget.Text.Primary>
    </Widget.TextWidget>
  );
};

Programmatically

Use these functions to get and set settings. They’re available from both attio/client (for use in React components, actions, etc.) and attio/server (for use in server functions): In client code:
record-action.tsx
import { 
  experimental_getWorkspaceSettings,
  experimental_getWorkspaceSetting,
  experimental_setWorkspaceSetting 
} from "attio/client";
import type { App } from "attio";

export const syncAction: App.Record.Action = {
  id: "sync-record",
  label: "Sync Record",
  icon: "Refresh",
  onTrigger: async ({ recordId }) => {
    // Get all settings
    const settings = await experimental_getWorkspaceSettings();
    
    // Or get a single setting
    const syncEnabled = await experimental_getWorkspaceSetting("auto_sync_enabled");
    
    // Update a setting
    await experimental_setWorkspaceSetting("auto_sync_enabled", true);
  },
};
In server functions:
sync-data.server.ts
import { 
  experimental_getWorkspaceSettings,
  experimental_getWorkspaceSetting,
  experimental_setWorkspaceSetting 
} from "attio/server";

export default async function syncData() {
  // Get all settings
  const settings = await experimental_getWorkspaceSettings();
  
  // Or get a single setting
  const syncEnabled = await experimental_getWorkspaceSetting("auto_sync_enabled");
  
  // Update a setting
  await experimental_setWorkspaceSetting("auto_sync_enabled", true);
  
  return { success: true };
}
See the documentation for experimental_getWorkspaceSettings(), experimental_getWorkspaceSetting(), and experimental_setWorkspaceSetting() for more details.